没有 GCC 编译器警告的 C++11 变量缩小

标签 c++ c++11

缩小的概念似乎很简单。但是,有人可以解释为什么下面的某些代码会导致“缩小”编译器错误而其他代码不会吗?

这段代码会产生预期的错误:

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. 下,它继续给出了示例的一般列表:

[ Note: As indicated above, such conversions are not allowed at the top level in list-initializations.—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]

外部初始化列表...

我不认为将 float 截断为 int 被认为是 narrowing

这只是一个定义明确的转换,很像

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

关于没有 GCC 编译器警告的 C++11 变量缩小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8251059/

相关文章:

C++ 右值引用转发性能

c++ - 枚举值的类型不是 int?

c++ - OpenCV 束调整

c++ - 如何识别为什么程序未在docker内部启动

php - 如何使用 libcurl 从用 C++ 编写的游戏发布到我服务器上的 php 页面更安全?

c++ - 复制列表初始化是否在概念上调用复制构造函数?

C++ 使用 (void*) 转换为 int 进行比较?

c++ - E2321 声明未指定标签或标识符

c++ - 将二维数组作为函数参数并返回二维数组作为函数的返回类型

c++ - 非静态数据成员初始化