2

I have read this exam code.

"a.c":

int global_1 = 100;

"b.c":

extern int global_1;
int global_2 = global_1 * 2;

int main()
{
    return 0;
}

gcc give “error: initializer element is not constant"

I do not write this code, but I want to know why and how to fix.

Thanks.

lulyon
  • 6,707
  • 7
  • 32
  • 49

2 Answers2

3

The problem you are facing is that in order to initialise a variable (global_2 here) it's value (or all values of what it depends on, in your case global_1) need to be known.

When you initialise a variable in a function then it's value only needs to be known at runtime and that is generally the case or you will get an undefined symbol error during compile or link time.

Globals need to be initialised by the compiler during compile time.

extern int global_1;

Says to the compiler that global_1 exists, but not in this compilation unit. It will be accessible after linking. You can use it in functions, but the linker needs to link it first with an object file that actually contains it.

Thus the compiler is unable to initialise it at compile time resulting in the error you see. Linking comes after compiling.

If you need to initialise globals that reference globals in a different compilation unit then you will need to do this in a function. For example the first stem in main().

Sergey L.
  • 21,822
  • 5
  • 49
  • 75
  • Thanks for your kind explaining, but here really the problem is not about `extern`, and @alk 's answer have already solved my problem. So just give you the upvote. – lulyon Sep 06 '13 at 14:49
1

The error says it all: Initialisers need to be constants.

To fix this you might like to modify your code like this:

int global_2 = 0;

int main()
{
  global_2 = global_1 * 2;
alk
  • 69,737
  • 10
  • 105
  • 255
  • you mean the problem is `int global_2`? – lulyon Sep 06 '13 at 14:06
  • The problem is the *initialisation* of `global_2`. – alk Sep 06 '13 at 14:43
  • 1
    Not to muddy the water, but _IF_ you are using aggregate types (such as struct, array, union) and also using ANSI C99 extensions, then expressions are allowed during declaration/initialization, eg:`int gloabal_2[2] = {global_1*3, global_1*10};`. Important also to keep in mind what @Sergey has said below, that the entity used in any expression needs to be already initialized. – ryyker Sep 06 '13 at 15:04
  • 1
    One more thought, there is a great discussion [here](http://stackoverflow.com/questions/1433204/how-do-i-share-a-variable-between-source-files-in-c-with-extern-but-how) about sharing variables among many c modules (using externs) – ryyker Sep 06 '13 at 15:13