0

I am trying to initialize an array of size 2 via compound literals, the code with error is as below

int a[2] = (int[2]){1,2};

And the gcc compiler returns the bug saying

error: array initialized from non-constant array expression

From the gnu page for compound literals here https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html, it says "If all the elements of the compound literal are (made up of) simple constant expressions suitable for use in initializers of objects of static storage duration, then the compound literal can be coerced to a pointer to its first element and used in such an initializer". If I correct the above code into

int* a = (int[2]){1,2};

then it compiles successfully. I've also tried

static int a[] = (int [2]) {1, 2};

which also compiles successfully.

I'd like to understand why the original code cannot work, and why the compiler says the array is initialized from non-constant array expression (from my understanding, 1 and 2 inside of the braces are integer literals that can be determined at compile time, hence constants).

asked May 20, 2023 at 2:22
4
  • 1
    Why do you want to use a compound literal opposed to regular initialization? int a[] = {1,2}; Commented May 20, 2023 at 2:35
  • @AllanWind I wouldn't use compound literals practical-wise. I am just learning about this language feature and curious when a seemingly legit thing doesn't work. Commented May 20, 2023 at 2:38
  • Compound literals Constructs an unnamed object of specified type . An instance of an object, not a "comma-separated list of . . . expressions that are initializers for array elements". It is not one of the forms accepted for Array initialization . Also note static int a[] = (int [2]) {1, 2}; also produces diagnostics from gcc Commented May 20, 2023 at 2:49
  • To quote from the page you referenced: "As a GNU extension, GCC allows initialization of objects with static storage duration by compound literals (which is not possible in ISO C99 because the initializer is not a constant)." Emphasis mine. Commented May 20, 2023 at 2:51

1 Answer 1

1

The C17 standard draft, 6.7.9 tells you there are two ways to initialize an array:

An array of character type may be initialized by a character string literal or UTF–8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.
...
Otherwise, the initializer for an object that has aggregate or union type shall be a brace-enclosed list of initializers for the elements or named members.

Perhaps more readable at cppreference.

answered May 20, 2023 at 2:50
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the reply. I guess it just means that compound literal is not a valid way to initialize an array? As per the GNU document, I also tried putting the int a[2] = (int[2]){1,2}; in the global scope, hence static storage, and it compiles despite the compiler still produces the warning saying initializer element is not constant.
I think I understand what happens here now. "int a[2]" in C/C++ does not just mean let's call the size 2 integer array on the right hand side a", but rather the declaration itself is the process of allocating memories for two integers, and "a" stands both for the variable symbol as well a the array object itself. Hence "int a[2]={1,2}" is an initialization, rather than assignment. Hence "int a[2] = {int[]}{1,2}" cannot work as the right hand side returns the anonymous array object, and cannot be assigned nor used as initializer for the array "a". Hence only way is to decay RHS into a pointer .
Yes, that's correct.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.