7

When a struct that contains an array of struct pointers is instantiated, am I guaranteed that all pointers in the struct array member will be set to NULL?

Here's an example struct:

typedef struct mmNode {
  int val;
  int board[2][NUM_PITS+1];
  int side;
  struct mmNode* children[NUM_PITS+1];
} mmNode;

IE: If I create an instance of the mmNode struct, will the elements of mmNode.children always be set to NULL?

Jitsusama
  • 617
  • 7
  • 20
Zahy
  • 367
  • 7
  • 18

1 Answers1

17

It depends how you initialise your struct.

mmNode a;                              // Everything default-initialized

void foo()
{
    static mmNode b;                   // Everything default-initialized

    mmNode  c;                         // Nothing initialized
    mmNode  d = { 0 };                 // Everything default-initialized
    mmNode *p = malloc(sizeof(*p));    // Nothing initialized
    mmNode *q = calloc(1, sizeof(*q)); // Everything zero-initialized
}

"Nothing initialized" means that all members will just have random junk values. "Default-initialized" means that all members will be initialized to 0, which for pointer members will be equivalent to NULL. "Zero-initialized" means that everything will be set, bitwise, to 0. This will only work on platforms where NULL is represented with bitwise 0.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • 1
    Will `calloc` correctly initialize `NULL` pointers ? I mean will `all-bits 0` always mean `NULL` ? – cnicutar Aug 14 '11 at 13:16
  • 1
    My GCC (4.6.1) gives me a warning "missing initialiser" when I write `= {0}`. Are you sure that's legit? – Kerrek SB Aug 14 '11 at 13:16
  • 3
    @cnicutar: No. "Zero-initialisation" isn't the same as "null-initialisation". The underlying representation of a pointer whose value was assigned the null pointer literal needn't be `0`. `[C99:6.3.2.3/3]` – Lightness Races in Orbit Aug 14 '11 at 13:22
  • @Kerrek: Hmm, strange. C99 section 6.7.8/21 should allow this, I think. But you're right, GCC doesn't like this with `-Wextra`. – Oliver Charlesworth Aug 14 '11 at 13:23
  • @Oli: I think I'd agree with you re: `{ 0 }` – Lightness Races in Orbit Aug 14 '11 at 13:25
  • @cnicutar: Yes, you're right. Hopefully the update to my answer addresses this. – Oliver Charlesworth Aug 14 '11 at 13:25
  • 3
    @Kerrek: According to http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#Warning-Options, `-Wextra` enables `-Wmissing-field-initializers`, which warns about this, even though it acknowledges that they're implicitly initialized to zero. – Oliver Charlesworth Aug 14 '11 at 13:28
  • Actually, I tried the following: mmNode* root = (mmNode*)malloc(sizeof(mmNode)); int i=0; for(i=0;i<8;i++){ if(root->children[i]!=NULL){ printf("%d:%d",i,root->children[i]); }else { printf("NULL!:%d:%d\n",i,root->children[i]); } } All nulls all the time! I am using gcc. Any explanations to that? – Zahy Aug 14 '11 at 14:06
  • Oli, Tomalak and @Kerrek. thanks. Please look at the attached code. Can anyone explain why this is happening? Sorry for the messed-up code, don't know how to format that. – Zahy Aug 14 '11 at 14:26
  • 3
    @Zahy: You can't format comments other than with backticks, but feel free to amend your original post! Also, being "indeterminate" includes the possibility of being zero - there's just no guarantee. – Kerrek SB Aug 14 '11 at 14:42
  • @Kerrek SB: `{ 0 }` is a valid initialiser - gcc chooses to warn because you *might* have made a mistake, but it's still valid C. – caf Aug 15 '11 at 05:41
  • 1
    note: "Zero-initialized" and "Default-initialized" are terms that have been invented for this answer. They do not appear in the C standard. The C++ standard does use those terms, but with very different meanings. – M.M Jul 25 '14 at 00:17