Dpp
Dpp

Reputation: 1974

What does "int *a = (int[2]){0, 2};" exactly do?

I was very surprised when I saw this notation. What does it do and what kind of C notion is it?

Upvotes: 11

Views: 838

Answers (5)

Sjoerd
Sjoerd

Reputation: 75649

  • {0, 2} is the notation for an array consisting of 0 and 2.
  • (int[2]) casts it to an array (don't know why).
  • int * a = assigns it to the int pointer a.

Upvotes: -2

Pete Kirkham
Pete Kirkham

Reputation: 49331

This is a compound literal as defined in section 6.5.2.5 of the C99 standard.

It's not part of the C++ language, so it's not surprising that C++ compilers don't compile it. (or Java or Ada compilers for that matter)

The value of the compound literal is that of an unnamed object initialized by the initializer list. If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.

So no, it won't destroy the stack. The compiler allocates storage for the object.

Parenthesis are put around the type and it is then followed by an initializer list - it's not a cast, as a bare initialiser list has no meaning in C99 syntax; instead, it is a postfix operator applied to a type which yields an object of the given type. You are not creating { 0, 3 } and casting it to an array, you're initialising an int[2] with the values 0 and 3.


As to why it's used, I can't see a good reason for it in your single line, although it might be that a could be reassigned to point at some other array, and so it's a shorter way of doing the first two lines of:

int default_a[] = { 0, 2 };
int *a = default_a;

if (some_test) a = get_another_array();

I've found it useful for passing temporary unions to functions

// fills an array of unions with a value
kin_array_fill ( array, ( kin_variant_t ) { .ref = value } )

Upvotes: 20

Scott Wales
Scott Wales

Reputation: 11706

This is a c99 construct, called a compound literal.

From the May 2005 committee draft section 6.5.2.5:

A postfix expression that consists of a parenthesized type name followed by a brace- enclosed list of initializers is a compound literal. It provides an unnamed object whose value is given by the initializer list.

...

EXAMPLE 1 The file scope definition

int *p = (int []){2, 4}; 

initializes p to point to the first element of an array of two ints, the first having the value two and the second, four. The expressions in this compound literal are required to be constant. The unnamed object has static storage duration.

Upvotes: 6

agsamek
agsamek

Reputation: 9064

(int[2]) tells the compiler that the following expression should be casted to int[2]. This is required since {0, 2} can be casted to different types, like long[2]. Cast occurs at compile time - not runtime.

The entire expression creates an array in memory and sets a to point to this array.

Upvotes: 0

yfeldblum
yfeldblum

Reputation: 65445

  1. Allocates, on the stack, space for [an array of] two ints.
  2. Populates [the array of] the two ints with the values 0 and 2, respectively.
  3. Declares a local variable of type int* and assigns to that variable the address of [the array of] the two ints.

Upvotes: 1

Related Questions