views:

245

answers:

2

From what I understand, #define x y and const int x = y; should work identically under the Visual Studio compiler, but const int x = y; is the preferred method.

The C code I have looks something like this:

static const int x = 100000;

void SomeFunction(...)
{
    volatile static int y = x;
    ...
}

The problem here is with the declaration of y. If I use a #define for x, then there are no problems, but using the above code results in the compiler returning with "error c2099: initializer is not a constant."

I'm trying to compile from the command line, and I'm not using any compiler flags, so I'm not sure if I need to set a flag in order for the compiler to optimize out the const - or if I stumbled onto some kind of special case.

Compiling the program as a C++ program also works, but I would rather avoid that, if possible.

A: 

This could be solved with another guard variable:

void SomeFunction(...)
{
    static int initialized_y=0;
    volatile static int y;
    if(initialized_y==0)
       y = x;
    initialized_y=1;
    ...
}

You could also turn this idiom into a macro.

jpalecek
+1  A: 

I don't know the C standard inside out but I've read about this before. Here's my understanding.

A strict ANSI C compiler will only allow you to use constant expressions as initialisers. Note that a constant expression can only involve literal values, not variables that are const-qualified.

I believe this is because during compilation, the compiler must compute the value to initialise so that it can statically push this value onto the stack without any computation required at runtime. Even const-qualified variables can change (by removing the const-qualifier and changing the value).

const int x = 5;
*(int *)&x = 3;

I think C99 allows you to initialise with const-qualified variables at function scope only, file-scope variables are still bound by the same restriction.

dreamlax
Changing the value of a const qualified variable is undefined behaviour - the standards committee wouldn't forbid it because of the possibility of an undefined behaviour
1800 INFORMATION
I'm sure it is undefined behaviour, but because it is undefined behaviour, some compilers could theoretically allow initialising from const-qualified variables. Microsoft's C compiler obviously doesn't though :(
dreamlax