Forum: Compiler & IDEs error: invalid suffix "+0x23" on integer constant


von Dennis (Gast)


Lesenswert?

Hallo,

bekomme beim compilieren folgende Fehlermeldung:

main.c:786:34: error: invalid suffix "+0x23" on integer constant

Zeile 786:

  int bcc=(0x04+voltmax+0x1B+0x4D+0x4E+0x23);

Füge ich Leerzeichen ein ist alles ok.
An anderer Stelle funktioniert das mit anderen Werten ohne Leerzeichen.
Wo liegt denn da der Fehler?
Gruß,
Dennis

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dennis wrote:

> Wo liegt denn da der Fehler?

In GCC's Parser für Zahlen.  Der Lexer besitzt nur einen einzigen
Parser, der sowohl für Integer- als auch Float-Zahlen benutzt wird.
Die Unterscheidung zwischen beiden erfolgt erst im Parser selbst, also
nachdem die Tokens bereits sortiert sind.  Dass das so gelöst ist,
dürfte mit dem Kozept einer `preprocessing number' zusammenhängen, die
ein zentraler Bestandteil der C-Syntax ist (Zahlen müssen bereits im
Präprozessor erkannt werden, nicht erst im Compiler):

6.4.8 Preprocessing numbers

...

  Semantics
4 A preprocessing number does not have type or a value; it acquires
  both after a successful conversion (as part of translation phase 7)
  to a floating constant token or an integer constant token.


Allerdings hat das Ganze einen Bug: der Substring

0x4E+0x23

wird als ein Token erkannt, da es mittlerweile ja auch hexadezimale
Gleitkommakonstanten gibt.  (Deren Vorteil ist die exakte Darstellung,
bei der es keine Rundungsfehler gibt.)  Die Fehlinterpretation rührt
aus dem ,E' in 0x4E her, das von einem Vorzeichen gefolgt wird, damit
also ein gültiger Exponent sein kann.  Da der Lexer noch nicht nach
Integer- und Gleitkomma unterscheidet, sortiert er die komplette 0x23
nach dem E+ als zur Zahl zugehörig.  Der Parser stellt dann fest, dass
der mit e eingeleitete Exponent nicht zu einer hexadezimalen
Gleitkommakonstanten passt, und sortiert den ersten Teil der Zahl als
Integerkonstante.  Damit ist dann aber der verbleibende Teil +0x23
nicht mehr passend, und der Bug triggert.

Ich weiß gar nicht, ob es dafür schon einen Bugreport gibt, wenn
nicht, dann schreib einen.

Den Bug kannst du übrigens einfach umgehen: schreib Leerzeichen um die
Pluszeichen (hattest du ja schon bemerkt).

von Dennis (Gast)


Lesenswert?

Ja, das macht Sinn.
Ich danke dir für die ausführliche Antwort!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Da es offensichtlich noch keiner getan hat:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33547

Bevor ich die Analyse noch ein drittes Mal machen muss. ;-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Umm, der Bugreport wurde geschlossen.  Das Ganze ist in der Tat ein
Feature -- und zwar eins der Sprache C.

Auszug aus dem C99 Rationale:

   6.4.8      Preprocessing numbers

   The notion of preprocessing numbers was introduced to simplify the
   description of preprocessing. It provides a means of talking about
   the tokenization of strings that look like numbers, or initial
   substrings of numbers, prior to their semantic interpretation. In
   the interests of keeping the description simple, occasional
   spurious forms are scanned as preprocessing numbers. For example,
   0x123E+1 is a single token under the rules. The C89 Committee felt
   that it was better to tolerate such anomalies than burden the
   preprocessor with a more exact, and exacting, lexical
   specification. It felt that this anomaly was no worse than the
   principle under which the characters a+++++b are tokenized as a
   ++ ++ + b (an invalid expression), even though the tokenization a
   ++ + ++ b would yield a syntactically correct expression. In both
   cases, exercise of reasonable precaution in coding style avoids
   surprises.

Wenn das kein Argument gegen C ist...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.