mikrocontroller.net

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


Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: Dennis (Gast)
Datum:

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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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. ;-)

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.