Super Mario
Super Mario

Reputation: 939

Initialization array of structs - {NULL} vs {}

If I have this struct:

typedef struct MyStruct
{
    int type1;
    char *type2;
    char type3[CHARS_AMOUNT];
} MyStruct;

What would be the difference between following initialization:

option 1:

int main(int argc, char *argv[])
{
    MyStruct someObjects[5] = {};
}

option 2:

int main(int argc, char *argv[])
{
    MyStruct someObjects[5] = {NULL};
}

Upvotes: 3

Views: 4088

Answers (3)

AnT stands with Russia
AnT stands with Russia

Reputation: 320391

The first version is immediately illegal. C language does not support {} initializers.

The second version is generally illegal, even though it might "compile" in some implementations. In this case, in accordance with the rules of aggregate initialization your NULL will act as an initializer for someObjects[0].type1 field. This field has type int. However, even though in many implementations you might be able to successfully initialize int objects with NULL, in general case it is not possible. NULL is intended to be used in pointer context, not in integer context.

If you want to zero-initialize your entire array, the proper way to do it is

MyStruct someObjects[5] = { 0 };

Upvotes: 2

Petr Skocik
Petr Skocik

Reputation: 60058

MyStruct someObjects[5] = {}; isn't conformant C and whether MyStruct someObjects[5] = {NULL}; is conformant C is implementation defined*.

You should initialize it with MyStruct someObjects[5] = {0};. {0} is the way to default/zero-initialize any array, aggregate object or compound literal in C.

{0} works for default/zero-initialization because 6.7.9p19 and 6.7.9p20 will cause the 0 to recursively target the first primitive object, because every primitive data object in C is either numerical or a pointer and therefore initialiazable with 0 and finally because 6.7.9p21 says that:

If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.


*NULL could be defined as 0 in which case {NULL} is OK, or it could just as well be defined (void*)0 in which case {NULL}'s not OK in your case because recursively, you're array's first primitive object (int type1;) is not a pointer initalizable from (void*) or even a pointer.

Upvotes: 2

Keith Thompson
Keith Thompson

Reputation: 263217

The difference is that the first is illegal in standard C, and the second may or may not be.

{} in an initializer is not legal in C; you need at least one element between the { and }. (Some compilers might permit it as an extension; I think gcc does.)

A common idiom is

some_type blah[] = { 0 };

The initial element is initialized to 0 (which could be a null pointer, floating-point zero, a null character, etc.), and the remaining unspecified elements are initialized to zero for the appropriate type.

With the {NULL} initializer you're trying to initialize someObjects[0].type1, an int to NULL. The NULL macro is intended to be used as a null pointer constant. It may or may not be defined as a constant 0, so the legality of your initializer is implementation-specific.

Just write

MyStruct someObjects[5] = {0};

Upvotes: 4

Related Questions