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 bug数据库,没有找到任何相关的东西。谢谢!
说实话,我觉得你们的样品没什么不对。
然而,在许多情况下,编译器似乎接受"违反"标准转换规则的行为…:
初始化项列表(§8.5.4)
然而,我在标准中发现了这个:
对于初始化器列表,不允许(§8.5.4,3.)
int ai[] = { 1, 2.0 }; // error narrowing
在<<p> strong> 6。它接着给出了一个通用的示例列表:
[注意:如上所述,在list-initialization . - end的顶层不允许这样的转换注意]
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
有趣的是,g++ 4.6.1与--std=c++0x -Wall -pedantic
只捕获了中的一个:
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
浮点数可以转换为整型:
浮点型的右值可以转换为整型的右值。转换轮盖茨;也就是说,小数部分被丢弃。如果截断的值不能为,则行为未定义以目标类型表示。
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右值
2. 右值不适合char类型
int d = 256;
unsigned char e = d; // Maybe OK because 'd' is not constexpr
这段代码不是正在缩小的右值。这是从int到unsigned char的隐式强制转换。
相关文章:
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 初始化迭代器错误 C++ 在 GCC 编译器中
- #pragma(*诊断)当将Clang分析器与GCC编译器混合时
- 为什么 gcc 编译器标志未知?
- 如何使用 GCC 编译器优化创建静态库?
- GCC 编译器是否应该对涉及 [[fallthrough]] 属性的格式错误的C++代码进行诊断?
- 如何在macOS中的旧扩展clang和gcc编译器中初始化数组和向量
- gcc c++编译器中的零大小数组
- 相对于继承的构造函数,gcc 编译器是否还有一个错误?
- template-id 与任何模板声明 GNU gcc 编译器都不匹配
- 关于 PBC 库在 GCC 编译器在 DEV C++ 中使用
- 选择默认的 gcc/g++ 编译器
- GCC编译器,为较低版本的GCC编译应用程序
- 相同的代码在不同的 gcc 编译器中存在巨大的性能差异
- GCC 编译器对类型转换有什么作用?为什么 mac 和 Linux 上的输出不同
- GCC 编译器错误:stl_construct.h、stl_uninitialized.h
- 如何从我的qt应用程序运行gcc编译器?
- GCC 编译器错误:stl_construct.h
- 升级 gcc 编译器/其他修复程序以向后兼容
- GCC 编译器一个字节中有多少位