A. K.
A. K.

Reputation: 38214

default initialization of aggregates

For the following program, I do not get a warning that uoff.Reg and s.i is used without initialization. gcc (with -Wextra) and clang (with -Weverything) both do not warn, as I expected.

#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);
}

I'm wondering why I'm not getting any warning. Does standard (C/C++) say that aggregates with automatic storage are initialized (by default) to zero, or is it a compiler limitation?

Upvotes: 0

Views: 979

Answers (4)

alk
alk

Reputation: 70971

No, the C-Standard does not require the compiler to generate code to initialise auto variables. Reading their value without prior initialisation provokes undefined behaviuor.

However, this code

int main(void)
{
  int a;
  int b = a;
  b = b;

  return 0;
}

compiled using gcc's option -Wall, gives:

main.c:4: warning: ‘a’ is used uninitialized in this function

[gcc (Debian 4.4.5-8) 4.4.5]

Upvotes: 1

juanchopanza
juanchopanza

Reputation: 227498

In order to guarantee zero-initialization of POD aggregate data members, you need to value-initialize your instance. For example,

st s = st(); // C++03 and C++11
st s = {};   // C++03 and C++11
st s{};      // C++11

Compilers are not required to warn you about uninitializad variables. However, the minimal set of compilation flags needed to get a warning with g++ seem to be

-Wuninitialized -O2

In other words, it seems that without optimization, the warning disappears. It could be that in this case variables get zero initialized.

Upvotes: 2

Filipe Gon&#231;alves
Filipe Gon&#231;alves

Reputation: 21223

Does standard (C/C++) say that aggregates with automatic storage are initialized (by default) to zero

No, it doesn't. Automatic variables are not initialized, their value is initially left undefined. Using them without initialization results in undefined behavior.

However, naturally, the standard doesn't require you to initialize variables, compilers are free to warn about this, but using an uninitialized variable is not a constraint violation, thus, implementations do not have to warn you.

Upvotes: 1

marcinj
marcinj

Reputation: 50026

I checked gcc, : http://coliru.stacked-crooked.com/a/f1b25f7f369fbdbc, and warnings does get generated

here is how it gets compiled:

g++-4.8 -std=c++11 -O2 -Wall -pedantic -pthread main.cpp && ./a.out

and output:

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

Upvotes: 3

Related Questions