0

Is a const compound literal a valid initializer for a static variable?

#define COMPOUND    ((const int [2]){1, 2})

static const int    x   = COMPOUND[0];
/* static const int x   = 1; should be equivalent */

EDIT:

The possible duplicacte in the first comment doesn't make sense, because I'm asking explicitly about const literals, and not variables.

  • 1
    Possible duplicate of [Error "initializer element is not constant" when trying to initialize variable with const](https://stackoverflow.com/questions/3025050/error-initializer-element-is-not-constant-when-trying-to-initialize-variable-w) – kiran Biradar Feb 08 '19 at 15:24
  • That question doesn't ask about `const` compound literals but simple `const`s. I know I can not use a `static const` variable as initializer, but you can see here I am not using a variable, but a literal, which might be different. – alx - recommends codidact Feb 08 '19 at 15:27
  • The GCC manual says it's an extension (https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Compound-Literals.html). – Petr Skocik Feb 08 '19 at 15:35
  • It says so about compound literals, but not about `static` compound literals, which may (or not) be different. – alx - recommends codidact Feb 08 '19 at 15:36
  • 1
    @kiranBiradar: No, that is a different question. That asks about initializing with an object. This asks about initializing with a compound literal. – Eric Postpischil Feb 08 '19 at 15:41

1 Answers1

2

Yes, an element of a compound literal may be used as an initializer.

C 2018 6.7.9 4 tells us what initializers must be:

All the expressions in an initializer for an object that has static or thread storage duration shall be constant expressions or string literals.

6.6 tells us what constant expressions may be. Paragraph 3 says:

Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within a subexpression that is not evaluated.

Paragraph 4 says:

Each constant expression shall evaluate to a constant that is in the range of representable values for its type.

Paragraph 7 expands this to:

More latitude is permitted for constant expressions in initializers. Such a constant expression shall be, or evaluate to, one of the following:

  • an arithmetic constant expression,
  • a null pointer constant,
  • an address constant, or
  • an address constant for a complete object type plus or minus an integer constant expression.

None of the other paragraphs prohibit the use of compound literals, so they are permitted.

Community
  • 1
  • 1
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • I'll wait a bit to see if someone finds something in the opposite way, but I think this makes sense. – alx - recommends codidact Feb 08 '19 at 15:31
  • However, the compiler I'm using (XC8) refuses to compile :( – alx - recommends codidact Feb 08 '19 at 15:33
  • 2
    @CacahueteFrito: Does it claim to be compliant with C 1999 or later? Is it complaining about the compound literal or the initializer? What is the exact error message? Your code compiles in Apple LLVM 10.0.0 with clang-1000.11.45.5 with only a warning about the unused `x`. – Eric Postpischil Feb 08 '19 at 15:37
  • It is compliant with C99 (or at least that's what it claims) (not C11), but compound literals are there since C99, right? – alx - recommends codidact Feb 08 '19 at 15:39
  • The error is: `main.c:51:: error: (712) can't generate code for this expression` for this line: `static const int x = ((const int [2]){1, 2})[0];` – alx - recommends codidact Feb 08 '19 at 15:41
  • Does it still accept it in strict --std=c11 (or 99) mode (without gnu extensions)? – alx - recommends codidact Feb 08 '19 at 15:44
  • 2
    @CacahueteFrito: Yes, starting around version 4.7.1. (Version 4.1.2 does not recognize `-std=c11`.) – Eric Postpischil Feb 08 '19 at 15:46
  • 3
    It gives me some concern that 6.6 7 broadens the constant expressions for initializers, saying that “More latitude is permitted,” and then says they shall be an arithmetic constant expression or one of several pointer/address things, and then paragraph 8 defines *arithmetic constant expression* to have only limited operands that do not include compound literals. That would seem to be less latitude, not more. But it is also defective in that operands may be other arithmetic constant expressions. The C standard is not perfect. – Eric Postpischil Feb 08 '19 at 16:00