8

I've been trying to run a C file from https://github.com/amree/mykad-c/blob/master/scdump.c, but I keep getting Invalid suffix "-252" on integer constant at this part of the code:

        if (RxBuffer[0x11E-252] == 'P')
            printf("Female\n");
        else if (RxBuffer[0x11E-252] == 'L')
            printf("Male\n");
        else
            printf("%c\n", RxBuffer[0x11E-252]);

I'm pretty sure it's syntax related. But I don't really understand code (I'm trying to, but I'm pretty much stuck). Can anyone help me?

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
Amree
  • 2,890
  • 3
  • 30
  • 51
  • What compiler are you using? This is a compiler bug that was present in gcc 2.95, perhaps early gcc 3.x, and perhaps other compilers. – R.. GitHub STOP HELPING ICE Aug 16 '12 at 00:17
  • @R. - this error occurs for me with a fairly recent gcc 4.6.1 - there's a bug closed as "RESOLVED INVALID": http://gcc.gnu.org/bugzilla/show_bug.cgi?id=3885 There's an open bug that's tracking making the diagnostic friendlier: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24976 – Michael Burr Aug 16 '12 at 00:55
  • @R..: I'm using Qt Framework, so I guess I'm using GCC compiler? I got the same error on Windows (MingW) and Linux (modified to use pcsc-lite) (gcc 4.5.2) – Amree Aug 16 '12 at 01:47
  • See my comments on the accepted answer. GCC is doing the right thing, but the answer's explanation of it is wrong. – R.. GitHub STOP HELPING ICE Aug 16 '12 at 02:07

2 Answers2

12

While this problem is related in a way to hex floating point constants, the root cause of the problem isn't because 0x11E is the start of a hex float constant (because it's not the start of a hex floating constant).

The problem is that 0x11E-252 is a single token instead of three tokens like 0x11F-252 is. If you look at C99 6.4.8 "Preprocessing numbers", you'll see that a pp-number token is:

A preprocessing number begins with a digit optionally preceded by a period (.)and may be followed by valid identifier characters and the character sequences e+, e-, E+, E-, p+, p-, P+, or P-

So, 0x11E-252 is a single token and tokenizing occurs in translation phase 3, but when it comes time to interpret the token syntactically and semantically (which happens in translation phase 7), it's not syntactically valid so you get a compiler error.

On the other hand, 0x11F-252 is three tokens because the - is not part of a preprocessing number token unless it's immediately preceded by a P or E (upper or lowercase).

Of course, this is related to float constants (hexadecimal or otherwise) because that's why the - character can end up in the middle of a preprocessing number token. However, note that you will get a similar error messages for tokens like 0xx11F or 22bad_token which have no resemblance to a hex floating point constant.

The fix is as ouah noted, insert whitespace before the - to force the compiler to treat the sequence as more than one token. If this were your code, an even better solution might be to give names to all those magic numbers (enums or macros). An identifier followed by - won't be considered a single token. Plus you'd hopefully have the bonus of making the code a little more self documenting.

Community
  • 1
  • 1
Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • See the end of http://gcc.gnu.org/onlinedocs/gcc/Incompatibilities.html for explicit GCC documentation on this issue. – Michael Burr Aug 16 '12 at 00:58
6
0x11E-252

is an hexadecimal floating point constant in C and -252 is the exponent part. You get the warning because you are initializing an integer object with a float constant.

0x11E - 252  // Note the whitespace

is an integer expression.

Use the latter to have the desired behavior.

EDIT:

my answer is actually not true. While the fix is OK, see the answer from @MichaelBurr for the real explanation of what's going on. 0x11E-252 is a read as a single token under C rules and it is not a valid floating (or integer) number.

Community
  • 1
  • 1
ouah
  • 142,963
  • 15
  • 272
  • 331
  • 2
    This is not a warning, this is an error, because hex FP constants use `p` instead of `e` (since `e` is a valid hex digit). Here is a [link](http://stackoverflow.com/a/4825867/335858) explaining hex float constants of C99. – Sergey Kalinichenko Aug 15 '12 at 22:07
  • Well I meant warning in the sense of C diagnostic. – ouah Aug 15 '12 at 22:10
  • Ah, I see. Nice answer, by the way (+1). – Sergey Kalinichenko Aug 15 '12 at 22:12
  • 2
    This is wrong. It's not a hex float constant. OP's compiler is buggy and wrongly treating it as one. The exponent character in hex floats is `P` not `E`. – R.. GitHub STOP HELPING ICE Aug 16 '12 at 00:16
  • Hmm.. Even though the error is gone and I can compile happily, I can't produce the correct value by just adding space in the front. This code used to work (the repo has its binary and it produces the correct value). – Amree Aug 16 '12 at 01:50
  • OK, it's not a hex float, but it is a preprocessor token, and thus the C language requires it to be parsed as a single token and therefore treated as an error. – R.. GitHub STOP HELPING ICE Aug 16 '12 at 02:06
  • @foo: I don't know if it's the cause of the difference you're seeing, but this line in `TrimString()` has undefined behavior: `for (j=0; j – Michael Burr Aug 16 '12 at 05:52
  • 1
    @foo could you accept MichaelBurr answer instead of mine, so I can delete my answer? – ouah Aug 16 '12 at 15:20