0
votes

Compiler: Microsoft Visual C++ 2010 Express, SP1 Project Property: C/C++ Advance Compile As: Compile as C Code (/TC)

Message:

error C2099: initializer is not a constant

Simple Test Case Showing Error:

typedef struct
{
    char *stringP;
    int  lino;
} foo_t;


#define bad {static foo_t foo ={__FILE__,__LINE__};}
#define good {static foo_t foo ={"filename",10};}

int main()
{

    bad;        // error C2099: initializer is not a constant
    good;       // no error

    return 0;
}

This generates a C2099 error. This code compiles & links correctly under gcc but not Visual C++ 2010 Express (compile as C Code - i.e. /TC option).

3
Can you provide a complete example that can be copied and pasted and compiled to demonstrate the problem? - James McNellis
Not sure if this isn't going to bite you someday: on many present-day computers, int is 32 bits; long is 64 bits -- you are defining some identifiers with misleading names: #define Word16 int; #define Word32 long int. If you can think about using C99 fixed-width types. ` - pmg
Thanks - I just did a quick test case and I was sloppy. This, of course, is not relevant to my bug. - Robert Friedman
I can compile the sample code without error using Visual C++ 2010 RTM (except, of course, that the linker doesn't like there being no definition for probe_). - James McNellis
Do not use void main()! Except in exceedingly rare instances, you should always define main as either int main() or int main(int, char**). - Adam Rosenfield

3 Answers

0
votes

Your code compiles well on my system (MS Visual Studio 2005).

You can preprocess your code to try finding the problem manually:

cl your_file.c /E > stuff.c

This generates a preprocessed file (you probably have to supply a whole lot more command-line options; you can copy-paste them from the project's Property Pages).

cl stuff.c

This should reproduce the problem. Then try looking at the code in stuff.c; if you don't see the problem immediately, try tweaking it (e.g. replacing complex things with 0) - this should hint on the problem.

(Since your system is much newer than mine, some details may be different, e.g. maybe the compiler on your system is called something other than cl, but the idea will probably work)

0
votes

For some reason the Microsoft C compiler does not recognize the __LINE__ preprocessor macro as a constant (presumably because it changes from line to line?), so you can't use it to initialize a structure member.

Generating the preprocessed .i file doesn't really help because it generates legal code that compiles just fine after __LINE__ has been replaced with a constant. Apparently, the C compiler is not trying to compile this same preprocessed output.

You should be able to use

foo.lino = __LINE__;

later without any problems. This seems to be a gripe from the Microsoft C compiler. Other C compilers I've used don't seem to have any problems with this use of __LINE__.

The only workaround I've been able to find is to compile the file as C++ code (/Tp).

0
votes

__LINE__ macro is not recognized as constant by MSVC compiler when "Edit & Continue" debug database mode is enabled. If you don't care about "Edit & Continue", you can switch to another database mode and the problem should disappear.