5

So I get the 'initializer element not constant' error when compiling the following code:

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

float wl = 2.0f;
float k = 2.0f * (float) M_PI / wl;

int main ()
{
     //Do stuff
}

If I move "float k" inside the main method, there's no errors, but this isn't an option for me, because I NEED float k to be a global variable. Even if I change it to this:

const float wl = 2.0f;
const float k = 2.0f * (float) M_PI / wl;

the error still happens. How do I fix this?

herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
Gribbles Chan
  • 123
  • 1
  • 3
  • 9
  • 1
    Consider assigning the value for `k` inside `main` at the very beginning, while declaring it as a global variable with no initialization. – Utkan Gezer Apr 13 '14 at 09:20

3 Answers3

7

According to 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.

Using const doesn't help here because, in C, const variables are not really const. Check out this post for more details.


To work out, you can make wl constant by using preprocessor:

#define wl 2.0f

By doing this, 2.0f * (float) M_PI / wl can be a compile time constant.

Community
  • 1
  • 1
herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
2

Global and static variables are stored in Data Segment(DS) when initialized and Block Start by Symbol(BSS) when uninitialized. These variables have a fixed memory location and memory is allocated in compile time .
C does not allow initialization of global values with non constant values.

C99 Standard: Section 6.7.8:

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

You need to move the initialization inside the main keeping declaration as global

float wl = 2.0f;
float k  ;

int main ()
{
      k = 2.0f * (float) M_PI / wl;
     //Do stuff
}
GoldRoger
  • 1,263
  • 7
  • 10
0

Above me @GoldRanger has accurately quoted the standard thus explaining the issue you're having. Technically since you have a variable in the initialization of k it's considered non-constant.

To add some context I'll put this here:

When the program compiles it puts the global variables in their own section of the binary (I'm not too familiar with linux or windows executable formats but on mac they are put in the __DATA segment). So when you put that line float k = 2.0f * (float) M_PI / wl; the compiler isn't smart* enough to recognize that wl is actually a constant at compile time and that you want k to be initialized with the initial value of wl.

*smart isn't exactly the right description here. In general since wl isn't declared as const the expression isn't exactly a constant expression in general so the compiler doesn't know anything about it. I suppose maybe this is a semantics issue or possibly just me arguing with myself over the wording I used.

In order to do what you're trying to do I usually use a #define for my initial constant that will be used throughout the program:

#define kwlconst 2.0f
float wl = kwlconst;
float k = 2.0f * (float) M_PI / kwlconst;
DanZimm
  • 2,528
  • 2
  • 19
  • 27