对于以下程序,我没有收到uoff.Reg
和s.i
未经初始化使用的警告。 gcc(with-Wextra)和clang(with -Weverything)都没有像我预期的那样发出警告。
#include<stdint.h>
typedef union {
uint32_t Reg;
struct {
uint16_t Cx;
uint16_t sf;
};
} tf;
typedef struct {
uint16_t i;
uint16_t j;
} st;
int bar(tf, tf);
int foo(tf t0, int32_t offset) {
tf uoff;
st s;
t0.Reg = uoff.Reg + s.i + (uint32_t)offset;
t0.sf = uoff.sf;
return bar(t0, uoff);
}
我想知道为什么我没有得到任何警告。标准(C / C ++)是否表示具有自动存储的聚合被初始化(默认情况下)为零,或者它是编译器限制?
答案 0 :(得分:3)
我检查了gcc,:http://coliru.stacked-crooked.com/a/f1b25f7f369fbdbc,并且生成了警告
这是如何编译的:
g ++ - 4.8 -std = c ++ 11 -O2 -Wall -pedantic -pthread main.cpp&amp;&amp; ./a.out
并输出:
main.cpp:10:3: warning: ISO C++ prohibits anonymous structs [-Wpedantic]
};
^
main.cpp: In function 'int foo(tf, int32_t)':
main.cpp:23:21: warning: 'uoff.tf::Reg' is used uninitialized in this function -Wuninitialized]
t0.Reg = uoff.Reg + s.i + (uint32_t)offset;
^
main.cpp:23:21: warning: 's.st::i' is used uninitialized in this function -Wuninitialized]
/tmp/ccIy8fGt.o: In function `foo(tf, int)':
main.cpp:(.text+0xa): undefined reference to `bar(tf, tf)'
collect2: error: ld returned 1 exit status
答案 1 :(得分:2)
为了保证POD聚合数据成员的零初始化,您需要 value-initialize 您的实例。例如,
st s = st(); // C++03 and C++11
st s = {}; // C++03 and C++11
st s{}; // C++11
编译器不需要警告您有关uninitializad变量的信息。但是,使用g ++获取警告所需的最小编译标志集似乎是
-Wuninitialized -O2
换句话说,似乎没有优化,警告就会消失。可能是在这种情况下变量初始化为零。
答案 2 :(得分:1)
不,C-Standard不要求编译器生成代码来初始化自动变量。在没有事先初始化的情况下阅读它们的价值会引发不确定的行为。
然而,这段代码
int main(void)
{
int a;
int b = a;
b = b;
return 0;
}
使用gcc的选项-Wall
编译,给出:
main.c:4: warning: ‘a’ is used uninitialized in this function
[gcc(Debian 4.4.5-8)4.4.5]
答案 3 :(得分:1)
标准(C / C ++)是否表示具有自动存储的聚合 初始化(默认情况下)为零
不,它没有。自动变量未初始化,其值最初未定义。在没有初始化的情况下使用它们会导致未定义的行为。
然而,当然,标准不要求你初始化变量,编译器可以自由地警告这一点,但使用未初始化的变量不是约束违规,因此,实现不必警告你。