什么是海湾合作委员会的Wmaybe单位化警告
what is gcc's Wmaybe-unitialized warning
我知道gcc中有一个未初始化的警告,它可以告诉您变量是否未初始化。这一点我很清楚。但我想知道什么是";也许已初始化";警告
gcc是否不确定这是否已初始化。或者考虑一下,代码是正确初始化的,gcc认为"也许";它没有被初始化。如果编译器不确定为什么我应该有这个警告?
现在我可以使用-Wno-maybe-uninitialized
禁用警告,或者在代码中进行修复。
但我的问题是,这意味着什么?为什么gcc认为它可能未初始化。gcc确信变量已初始化,因为我没有得到-Wuninitialized
。
我使用的是GCC 4.8 Fedora 21 x86_64。
此外,如果有人能展示这个警告是如何触发的,我将不胜感激。
在某些情况下,编译器可以清楚地检测到某些东西没有初始化:
void func1(int x);
void func()
{
int x;
func1(x); // x is definitely not initialized when calling func1;
}
但在某些情况下,变量CAN已经初始化:
void func(int y)
{
int x;
if (y == 1)
x = 7;
else if (y == 2)
x = 14;
// If we get here, is x initialized or not?
func1(x);
}
现在,如果您和我确信y
是ALWAYSonw或两个,那么上面的代码就没有问题。然而,如果我们用y
作为三来调用它,则x
尚未初始化,func1
将对未指定的值进行操作。如果启用-Wmaybe-uninitialized
,编译器将针对这种情况发出警告。
解决方法是告诉编译器不要期望任何其他值,例如使用assert
:
void func(int y)
{
int x;
assert( y == 1 || y == 2 && "Can't deal with y not in { 1, 2 } ");
if (y == 1)
x = 7;
else if (y == 2)
x = 14;
// If we get here, is x initialized or not?
func1(x);
}
现在,编译器将知道assert
的结果不允许y
为1或2以外的任何值,因此所有有效值都被覆盖。无效值被不返回的assert
捕获。
[当然,标准中并没有说明assert
具有这种效果。这是调用流分析与数据流分析以及对assert
功能的理解的一种效果——我知道gcc和clang都理解这种结构,并且会很乐意毫无征兆地接受上面的代码]
在提出此类问题之前,您应该仔细阅读GCC手册。
对于自动变量,如果存在来自函数的路径使用已初始化但存在的变量的条目变量未初始化的其他一些路径如果编译器无法证明未初始化的路径,则会发出警告在运行时不执行。这些警告是可选的,因为GCC不够聪明,无法了解代码可能尽管看起来有错误,还是要改正。
GCC不确定变量是否初始化时,不会生成此警告。它是在变量不总是初始化时发出的。
以下是手册中稍作修改的示例:
void foo(int y)
{
int x;
switch (y)
{
case 1: x = 1;
break;
case 2: x = 4;
break;
case 3: x = 5;
}
bar(x);
}
- 芬威克树(BIT).找到具有给定累积频率的最小索引,单位为 O(logN)
- RcppEigen 模板化函数,用于填充单位法线
- 如何有效地计算将单位立方体映射到自身的反射和旋转?
- 以天C++为单位的两个时间戳之间的差异
- 如何以毫秒为单位获取开始时间和 now() 之间的毫秒差异(以 C++为单位?
- 从原始字节解码协议缓冲区(以 C++为单位)
- ANTLR - 如何从维度扩展单位
- 如何在 c++ 中确定一条指令(以字节为单位)在哪里结束,另一条指令从哪里开始?
- 编写以 C++ 为单位返回值的函数
- 纹理单位重叠?渲染了错误的纹理
- Cuda:具有位集数组的 XOR 单位集
- 以C++为单位进行运行长度编码
- 如何找到两个日期之间的时间差异(以秒和纳秒为单位)?
- arr[n] 是否以 C++ 为单位打印数组的长度?
- 字符串数组上的 sizeof 运算符以 C++ 为单位给出不同的输出
- 以 C++ 为单位具有输出限制的排列
- 以 GDB 为单位指定浮点精度
- 整数数据如何以位为单位存储在内存中?不是右对齐吗?
- 如何在没有硬编码的情况下以C++为单位获取类数组的长度?
- 什么是海湾合作委员会的Wmaybe单位化警告