There is a (stupid) rule in C saying that any plain variable may be initialized with a brace-enclosed initializer list, just as if it was an array.
For example you can write int x = {0};
, which is completely equivalent to int x = 0;
.
So when you write int *nums = {5, 2, 1, 4};
you are actually giving an initializer list to a single pointer variable. However, it is just one single variable so it will only get assigned the first value 5, the rest of the list is ignored (actually I don't think that code with excess initializers should even compile with a strict compiler) - it does not get written to memory at all. The code is equivalent to int *nums = 5;
. Which means, nums
should point at address 5
.
At this point you should already have gotten two compiler warnings/errors:
- Assigning integer to pointer without a cast.
- Excess elements in initializer list.
And then of course the code will crash and burn since 5
is most likely not a valid address you are allowed to dereference with nums[0]
.
As a side note, you should printf
pointer addresses with the %p
specifier or otherwise you are invoking undefined behavior.
I'm not quite sure what you are trying to do here, but if you want to set a pointer to point at an array, you should do:
int nums[] = {5, 2, 1, 4};
int* ptr = nums;
// or equivalent:
int* ptr = (int[]){5, 2, 1, 4};
Or if you want to create an array of pointers:
int* ptr[] = { /* whatever makes sense here */ };
EDIT
After some research I can say that the "excess elements initializer list" is indeed not valid C - it is a GCC extension.
The standard 6.7.9 Initialization says (emphasis mine):
2 No initializer shall attempt to provide a value for an object not
contained within the entity being initialized.
/--/
11 The initializer for a scalar shall be a single expression,
optionally enclosed in braces. The initial value of the object is that
of the expression (after conversion); the same type constraints and
conversions as for simple assignment apply, taking the type of the
scalar to be the unqualified version of its declared type.
"Scalar type" is a standard term referring to single variables that are not of array, struct or union type (those are called "aggregate type").
So in plain English the standard says: "when you initialize a variable, feel free to toss in some extra braces around the initializer expression, just because you can."