Constant can't appear in a constant expression

Started by
1 comment, last by Gorax 18 years, 10 months ago
Don't bother reading this if you aren't bored out of your mind (I wont even care if nobody replies). I got bored, and decided to make something to read avis (WITHOUT VFW). It works as good as I had expected (wont read compressed data, and I don't plan on making it do so), however, I did come across a small problem when I tried to rewrite the MAKEFOURCC define macro to accept strings (to increase readability and save time), and I was wondering if anybody knew why.

//the new define macro, and an example of how it works
#define CreateRCode(name,str)   const unsigned int name = (str[0] | (str[1] << 8) | (str[2] << 16) | (str[3] << 24))
CreateRCode(RIFF_RCODE_RIFF, "RIFF");

//some code that belongs in a function:

//a variable
int n = RIFF_RCODE_RIFF;

//some code that works
printf("N == RIFF?: %d\n",n == RIFF_RCODE_RIFF);

//the code that doesn't work
switch (n){
  case 0: printf("ZERO\n"); break;
  case RIFF_RCODE_RIFF: printf("RIFF\n"); break; //this line wont work
}

//a working alternative (like MAKEFOURCC, only cleaner):
#define CreateRCode2(name,a,b,c,d)   const unsigned int name = (a | (b << 8) | (c << 16) | (d << 24))
CreateRCode2(RIFF_RCODE_RIFF,'R','I','F','F');

Incase you're wondering exactly what the compiler output is, it's this: `RIFF_RCODE_RIFF' cannot appear in a constant-expression. Also, I might as well mention that I'm using a combination of both CreateRCode and CreateRCode2, since I only use the switch statements when finding chunks that need to be discarded, but halting when there is garbage in the file, and I'd prefer not to have to use a giant if statement (since a giant switch statement is cleaner). ;)
Advertisement
Case labels must be integral constant expressions. A const variable is an ICE only if it is initialized by a constant expression. But a string literal is a pointer, and pointers are not allowed in a constant expression. Thus, for example,
const int i = 'a';switch(1) { case i: ; }

is legal, whereas
const int i = "a"[0];  // or *"a" or whateverswitch(1) { case i: ; }

is not.
Thanks for the info. Looks like I'll have to use an if statement after all... At least I can use define macros to cut that down a bit, even if it's not as clean. ;)

This topic is closed to new replies.

Advertisement