20

I'm coming from javascript/php/python and probably I'm missing something, here is the code:

const int a = 50;
const int c = 100;
const int d = 100;
int endX = c + a;
int endY = d;
int startX, startY, b;

I get

ex1.4.c:6: error: initializer element is not constant
ex1.4.c:7: error: initializer element is not constant

Does someone have an explanation?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
piggyback
  • 9,034
  • 13
  • 51
  • 80

5 Answers5

19

Unfortunately, in C const variables are not really const.

Below are the extracts from the c99 standard.

6.7.8 Initialization

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

The constants are defined as follows:

6.4.4 Constants

Syntax

constant:

integer-constant       (e.g. 4, 42L)
floating-constant      (e.g. 0.345, .7)
enumeration-constant   (stuff in enums)
character-constant     (e.g. 'c', '\0')

The standard defines constant expressions as follows:

6.6 Constant expressions

(7) 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 an object type plus or minus an integer constant expression.

(8) An arithmetic constant expression shall have an arithmetic type and shall only have operands that are integer constants, floating constants, enumeration constants, character constants, and sizeof expressions. Cast operators in an arithmetic constant expression shall only convert arithmetic types to arithmetic types, except as part of an operand to a sizeof operator whose result is an integer constant.

Thus, c and a are not constant expressions and cannot be used as initializers in your case.

Pritam
  • 339
  • 3
  • 23
Maksim Skurydzin
  • 10,301
  • 8
  • 40
  • 53
7

const expressions must be a compile time constant in C unlike in C++ therefore c+a can't be used as a constant. The usual way to handle this problem in C is to use the preprocessor instead:

#define A 50
#define C 100
#define D 100
int endX = C + A;
int endY = D;
int startX, startY, b;
none
  • 11,793
  • 9
  • 51
  • 87
  • 2
    if `c` and `a` are compile time constants, then `c+a` is as well (and anything to which that expression is assigned). It's not that C++ doesn't require const expressions to be compile-time constants; it's that C++ is smart enough to realize that `const int + const int` is a compile time constant, whereas C is not so smart. – weberc2 Jul 27 '14 at 14:14
5

If you are declaring endX as a global variable the error makes sense.

The reason is that global variables are initialized in compiling time, and you are trying to initialize endX as an operation that must be done in execution time.

Hernan Velasquez
  • 2,770
  • 14
  • 21
  • 10
    -1. This answer is wrong. There is nothing stopping the compiler from computing endX before execution time. In fact, g++will happily compile this. It's just GCC being overly cranky about what it will accept. – weberc2 Jul 23 '14 at 02:56
  • 1
    @weberc2 is correct. I tried this with clang compiler and it compiled and executed successfully. – ZeZNiQ Jan 23 '20 at 00:53
3

Yeah, you can't initialize something to a variable. The compiler does the initialization and at compile time it doesn't know the value of c+a;

The int x = 1; type initialization is fine, the compiler just puts a 1 at the address of x in the object code.

To initialize something to c+a, you want to do it at runtime, in the startup code in c or constructor in C++.

msc
  • 33,420
  • 29
  • 119
  • 214
Mark Stevens
  • 2,366
  • 14
  • 9
0

In C programming langages, objects with static storage duration must be initialized with constant expressions (or aggregate containing constant expressions). If endX has static storage duration, its initializer (c+a) is not a constant expression (i.e. the expression cannot be evaluated during translation phase).

md5
  • 23,373
  • 3
  • 44
  • 93