5

In some header file which I can not modify I have the following set of defines:

#define FLAG1                      (0x0000_0001)
#define FLAG2                      (0x0000_0002)
...

Then, in my code I use them in switch:

switch (aaa) {
    case FLAG1:
    ....

    case FLAG2:
    ....
}

As a result, Coverity reports on 2 defects per each case label:

RW.EXP_RPAREN: 
Event exp_rparen: expected a ")"

RW.CASE_LABEL_CONFLICT:
Event case_label_conflict: case label value has already appeared in 
this switch at line XX

What is wrong with these case labels? Does it violate C standards?

pmod
  • 10,450
  • 1
  • 37
  • 50
  • 1
    It shouldn't. `case 4*(1+2):` should be valid as well. – Linus Kleen Feb 10 '11 at 13:48
  • 10
    What is the underscore in 0x0000_0001? That's not valid C... – Johan Kotlinski Feb 10 '11 at 13:49
  • 1
    If you take out the underscores in the hex constants it should be fine. – Paul R Feb 10 '11 at 13:51
  • @kotlinski Actually, this underscore is accepted by compiler without any errors/warnings or other negative consequences... – pmod Feb 10 '11 at 13:58
  • If you can't get the header fixed, you are going to have to redefine the flag values yourself. You may as well use an `enum`. You might write (with slashes for newlines): `#undef FLAG1 / #undef FLAG2 / enum { FLAG1 = 0x0001, FLAG2 = 0x0002 };`. That undoes the damage from the erroneous header and gives you better debugging (because `enum` symbols are conveyed to the debugger, but preprocessor symbols usually are not). – Jonathan Leffler Feb 10 '11 at 13:59
  • 3
    If the underscore is accepted, you have a broken compiler - according to the C standard. Looking at it charitably, you have a compiler with a non-standard extension; don't try it with most compilers. And your syntax error becomes inexplicable. The C preprocessor won't object to the underscore; the C compiler should. **Which compiler** are you using? – Jonathan Leffler Feb 10 '11 at 14:01
  • @Jonathan Leffler. This is our preparatory compiler and now I have an idea to file a CR regarding this case. Thank you! – pmod Feb 10 '11 at 14:08

3 Answers3

5

Yes, you are allowed to have parentheses. What you aren't allowed to have is a number like 0x0000_0001.

That's not a valid hex number, you'll probably have to remove the _ character.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
3

Yeah, it's the underscore that's causing problems. FWIW, here are the relevant sections from the C language standard (draft n1256):

  • § 6.4.4.1 Integer Constants: defines the structure for integer constants and shows that _ is not a valid character for an integer constant;
  • § 6.6 Constant Expressions: defines the restrictions on constant expressions;
  • § 6.8.4.2 The switch statement: defines the restrictions on case labels in a switch statement.
John Bode
  • 119,563
  • 19
  • 122
  • 198
2

It think it expects the ) when it finds the _ which isn't valid in hexadecimal notation.

The compiler should actually complain like this:

error: invalid suffix "_0001" on integer constant

case labels may well contain parentheses:

switch(number) {
    // no way to determine operator 
    // precedence without parens here
    case 2*(1+2):
}
Linus Kleen
  • 33,871
  • 11
  • 91
  • 99
  • That isn't a suffix (according to the 'maximal munch' rule); it is an identifier starting with `_` that is adjacent to the hex constant - and you can't write a number followed by an identifier without an intervening operator. – Jonathan Leffler Feb 10 '11 at 13:54
  • Actually, this underscore is accepted by compiler without any errors/warnings or other negative consequences... – pmod Feb 10 '11 at 14:00
  • @Jonathan @Pmod Not my gcc, don't. I gave it `0xdead_beef` to "munch" and it complained with the exact same message I posted in the answer... [Lookie here](http://codepad.org/Bc06MUzJ) – Linus Kleen Feb 10 '11 at 14:01
  • The only reason for that is because it recognizes sometimes that the underscore could be embedded in a constant. Otherwise, the compiler will tokenize '`(0x0000_0001)`' into `(`, `0x000`, `_0001`, `)`, which is a pair of brackets around a valid number and a valid identifier. I can't find an option that allows it; I suspct it means there is some other compiler in the world that does allow it. I have verified that I get the message you show, Linus. – Jonathan Leffler Feb 10 '11 at 14:15