聚合的默认初始化

时间:2014-01-03 17:44:44

标签: c++ c gcc initialization compiler-warnings

对于以下程序,我没有收到uoff.Regs.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 ++)是否表示具有自动存储的聚合被初始化(默认情况下)为零,或者它是编译器限制?

4 个答案:

答案 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 ++)是否表示具有自动存储的聚合   初始化(默认情况下)为零

不,它没有。自动变量未初始化,其值最初未定义。在没有初始化的情况下使用它们会导致未定义的行为。

然而,当然,标准不要求你初始化变量,编译器可以自由地警告这一点,但使用未初始化的变量不是约束违规,因此,实现不必警告你。