[英]Why is this narrowing conversion not detected?
當使用list-initialization(如int x{ 5 };
)構造變量時,標准 §8.5.4說:
如果需要縮小轉換[...]來轉換任何參數,程序就會形成錯誤。 (7)變窄轉換是一種隱式轉換 - (7.4)從整數類型或無范圍枚舉類型到整數類型,它不能代表原始類型的所有值,除非源是一個常量表達式,其值在整數提升后將進入目標類型。
那為什么這會編譯?
char c{ 'A' };
char x{ c + c };
提醒一下, c + c
產生一個int
static_assert(std::is_same_v<decltype(c + c), int>, "");
所以編譯器應該抱怨縮小轉換,這肯定不是一個常數表達式。
有趣的是,將x
聲明為unsigned char
正確無法編譯:
char c{ 'A' };
unsigned char x{ c + c };
C2397從'int'轉換為'unsigned char'需要縮小轉換
和引入臨時一樣:
char c{ 'A' };
int sum{ c + c };
char x{ sum }; //C2397 conversion from 'int' to 'char' requires [...]
那么為什么第一個版本會編譯? 我正在使用Visual Studio Community 2017版本15.9.5並使用/wall
編譯,並且所有警告都在x64
調試版本中啟用了錯誤。 設置標准C ++ 11,C ++ 14和C ++ 17全部編譯。
我在這里提交了錯誤報告
是。 你說得對:程序結構不合理 。
在這種情況下( 標准§1.4 ):
符合要求的實施方案應至少發布一條診斷信息。
實際上, gcc
會發出警告信息。 clang
直接拒絕代碼作為編譯器錯誤。
這個特定的主題已經在這里討論了gcc 1 。
Visual Studio
應該生成一條診斷消息(我建議你檢查你的編譯選項。你是否禁用了警告?你是用C ++編譯的(11/14/17) ?,...)。 如果不是這種情況,那就是實施錯誤。
更新:
Visual Studio v19.20不會生成任何診斷消息(即使使用/Wall
標志)。
這里填寫了錯誤報告 。
1 有關gcc實施的其他信息,請在此處進行縮小檢查。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.