簡體   English   中英

C ++ 11變量縮小,沒有GCC編譯器警告

[英]C++11 Variable narrowing with no GCC compiler warning

縮小的概念似乎很簡單。 但是,有人可以解釋為什么下面的一些代碼導致“縮小”編譯器錯誤而其他代碼沒有?

此代碼在預期的位置產生錯誤:

constexpr int a = 255;
unsigned char b = a;      // OK
unsigned char c = a + 1;  // Error... expected

此代碼不會產生錯誤,但可能沒問題:

int d = 256;
unsigned char e = d;  // Maybe OK because 'd' is not constexpr

此代碼應該生成錯誤(除非我遺漏了一些東西):

int f = 42.0;  // Maybe OK because no fractional part
int g = 42.1;  // OK... should fail!!
constexpr float h = 42.7;
int i = h;     // OK... should fail???

我正在使用g ++ 4.6.2。 我搜索了GCC錯誤數據庫,沒有發現任何相關內容。 謝謝!

說實話,你的樣品我看錯了。

但是,在許多情況下,編譯器似乎接受“違反”標准轉換規則......:

初始化列表(第8.5.4節)

但是我在標准中發現了這個:

對於初始化列表,不允許以下內容(第8.5.4節,第3節

int ai[] = { 1, 2.0 }; // error narrowing

6.下,它繼續給出一個示例的一般列表:

[注意:如上所述,列表初始化中頂層不允許進行此類轉換。-end note]

int x = 999; // x is not a constant expression
const int y = 999;
const int z = 99;
char c1 = x; // OK, though it might narrow (in this case, it does narrow)
char c2{x}; // error: might narrow
char c3{y}; // error: narrows (assuming char is 8 bits)
char c4{z}; // OK: no narrowing needed
unsigned char uc1 = {5}; // OK: no narrowing needed
unsigned char uc2 = {-1}; // error: narrows
unsigned int ui1 = {-1}; // error: narrows
signed int si1 =
{ (unsigned int)-1 }; // error: narrows
int ii = {2.0}; // error: narrows
float f1 { x }; // error: might narrow
float f2 { 7 }; // OK: 7 can be exactly represented as a float
int f(int);
int a[] = { 2, f(2), f(2.0) }; // OK: the double-to-int conversion is not at the top level

有趣的是,帶有--std=c++0x -Wall -pedantic g ++ 4.6.1 捕獲其中一個違規行為:

    char c3{y}; // warning: overflow in implicit constant conversion [-Woverflow]

外部初始化列表......

我認為將浮點數截斷為int不會被視為narrowing

它只是一個定義明確的轉換,就像

int i = 31;
i /= 4;   // well defined loss of precision...   
i /= 4.0; // equally well-defined conversion from floating point to int

浮點可以轉換為整數:

浮點類型的prvalue可以轉換為整數類型的prvalue。 轉換轉發; 也就是說,丟棄小數部分。 如果截斷值無法在目標類型中表示,則行為未定義。

int f = 42.0;  // Equal to 42, 42 fits into int
int g = 42.1;  // Equal to 42, 42 fits
constexpr float h = 42.7;
int i = h;     // 42

縮小規則僅適用於初始化列表。

unsigned char c = { 2.4 }; // narrowing

warning: narrowing conversion of ‘2.3999999999999999e+0’ from ‘double’ to ‘unsigned char’ inside { } [-Wnarrowing]

此代碼在預期的位置產生錯誤:

constexpr int a = 255;
unsigned char b = a;      // OK
unsigned char c = a + 1;  // Error... expected

這會導致縮小錯誤,因為:
1.(a + 1)導致int rvalue
2. rvalue不適合char類型的有效范圍

int d = 256;
unsigned char e = d;  // Maybe OK because 'd' is not constexpr

此代碼不是縮小的右值。 它是從int到unsigned char的隱式轉換。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM