Forum: Compiler & IDEs Warum akzeptiert CubeMX dieses define nur in der Funktion?


von Ich lerne noch... (Gast)


Lesenswert?

Der Name ist Programm:
Inmitten einer eigenen C++-Datei (also z.B. da, wo die defines stehen) 
akzeptiert der Compiler folgendes nicht:
1
#ifdef DEBUG
2
    __HAL_DBGMCU_FREEZE_TIM2();   // Stop TIM2 during DEBUG
3
#endif
Schon vor dem Compilieren erscheint davor ein gelbes Fragezeichen mit 
Tooltip "Syntax error". Der erste Compilerfehler lautet
../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h:688:46: 
error: expected ')' before '*' token
  688 | #define DBGMCU              ((DBGMCU_TypeDef *)DBGMCU_BASE)
      |                              ~               ^
Packe ich das aber z.B. ganz am Anfang in eine meiner Funktionen, gibt 
es kein Problem. Das verstehe ich nun überhaupt nicht. Kann mir das 
bitte jemand erklären?

von Oliver S. (oliverso)


Lesenswert?

Da wirst du irgendwie irgendwo irgendwas falsch gemacht haben.

Oliver

von Émile (Gast)


Lesenswert?

Ich lerne noch... schrieb:
> Inmitten einer eigenen C++-Datei (also z.B. da, wo die defines stehen)
> akzeptiert der Compiler folgendes nicht:

Also außerhalb eines Funktionsrumpfes. Das Macro sieht aus wie ein 
Funktionsaufruf, also ist doch naheliegend, daß das nur innerhalb einer 
Funktion verwendet werden sollte.

von Steve van de Grens (roehrmond)


Lesenswert?

Was hat das mit CubeMX zu tun?

von Émile (Gast)


Lesenswert?

Das Macro kommt aus der STM32-HAL. Klingelt's?

von Steve van de Grens (roehrmond)


Lesenswert?

Émile schrieb:
> Das Macro kommt aus der STM32-HAL. Klingelt's?

Nein, die Datei gehört zur CMSIS, erkennt man unter anderem am Pfad. Wie 
dem auch sei, die Fehlermeldung sieht danach aus, als ob DBGMCU_TypeDef 
oder DBGMCU_BASE unbekannt sind. Das Makro an sich ist syntaktisch 
korrekt.

Allerdings sind diese Symbole beide in der selben Datei weiter oben 
definiert.

Wurde das Projekt eventuell vorher für ein anderes STM32 Modell erzeugt 
und enthält nun Reste davon? Kontrolliere nicht nur die Quelltexte, 
sondern auch die Definitionen in den Projekteinstellungen, insbesondere 
welche die so ähnlich wie "STM32F103xB" heissen (mit falscher 
Modelnummer).

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Steve van de Grens schrieb:
> die Fehlermeldung sieht danach aus, als ob DBGMCU_TypeDef
> oder DBGMCU_BASE unbekannt sind. Das Makro an sich ist syntaktisch
> korrekt.

Wie Emile ja auch schon geschrieben hat, steht die Ursache des Fehlers 
schon in der Überschrift, und die hat mit diesen Makros überhaupt nichts 
zu tun.

Innerhalb des ifdef/endif steht Code mit einem (oder mehreren) 
Funktionsaufruf(en) o.ä. in einem Makro, der nur innerhalb einer 
Funktion zulässig ist. gcc wirft daher eine völlig kryptische 
Fehlermeldung aus dem eigentlichem Makro.

Oliver

: Bearbeitet durch User
von FOp (Gast)


Lesenswert?

Es gibt da wohl ein SFR (Special Function Register) mit dem schönen 
Namen DBGMCU.

In einer der vielen Header Dateien (um genau zu sein in 
../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h Zeile 688), 
gibt es ein passendes Define, dass veranlasst, dass die 
Buchstabenkombination DBGMCU durch lustigen 
Integer-zu-Pointer-und-dann-Zugriff-auf-jenigen C-Code ersetzt wird.

Das passiert zu Deiner Verwunderung halt auch mitten in Deinem 
Funktionsnamen.

Nach dem der Precompiler Euch dieses Ei gelegt hat, hat der C-Compiler 
keine Ahnung, wie er
1
__HAL_((DBGMCU_TypeDef *)0x4711UL)_FREEZE_TIM2();

übersetzen soll.

von Mike R. (thesealion)


Lesenswert?

FOp schrieb:
> Das passiert zu Deiner Verwunderung halt auch mitten in Deinem
> Funktionsnamen.

Wenn das passieren würde, dann sollte er den Compiler wegschmeißen. 
(Oder FOp sollte sich ein C-Buch kaufen).

Die Lösung findet sich doch schon bereits einen Post höher:
Oliver S. schrieb:
> Wie Emile ja auch schon geschrieben hat, steht die Ursache des Fehlers
> schon in der Überschrift, und die hat mit diesen Makros überhaupt nichts
> zu tun.

Um es kurz zu sagen: Programmcode gehört in eine Funktion und nicht 
irgendwo in die Datei.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Oliver S. schrieb:
> Wie Emile ja auch schon geschrieben hat, steht die Ursache des Fehlers
> schon in der Überschrift, und die hat mit diesen Makros überhaupt nichts
> zu tun.

Eigentlich gibt es in der Überschrift
1
"Warum akzeptiert CubeMX dieses define nur in der Funktion?"
2
                                ^^^^^^
sogar einen Doppelfehler.

Es handelt sich nämlich gar nicht um ein #define. Ein solches würde 
nämlich außerhalb von Funktionen durchaus akzeptiert werden - das ist 
sogar der Normalfall.

von DerEinzigeBernd (Gast)


Lesenswert?

Frank M. schrieb:
> Es handelt sich nämlich gar nicht um ein #define.

Macros aber sind #defines, oder hat C mittlerweile einen neuen, anderen 
Mechanismus, um Macros zu definieren?

Man könnte sich jetzt nur noch darum streiten, ob die Verwendung eines 
Macros als "#define" bezeichnet werden sollte, oder nur die Definition.

Und letztlich ist jedes #define ein Macro. Auch wenn da nur

#define bla 100

steht, das ist auch ein Macro. Was anderes kennt der Präprozessor gar 
nicht.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

DerEinzigeBernd schrieb:
> Macros aber sind #defines,

Was soll das? Du weißt genau, was ich meine. Im Eröffnungsposting steht 
kein #define, nur etwas, was ein Aufruf eines Makros sein könnte, 
welches in einen Funktionsaufruf mündet - falls es nicht sogar direkt 
ein Funktionsaufruf ist.

Konstruiere also bitte kein eventuelles Missverständnis. Ein #define 
kann man überall anbringen - egal ob innerhalb oder außerhalb von 
Funktionen. Und der TO wundert sich, dass genau das nicht 
funktioniert.

: Bearbeitet durch Moderator
von Nachdenklicher (Gast)


Lesenswert?

FOp schrieb:
> Das passiert zu Deiner Verwunderung halt auch mitten in Deinem
> Funktionsnamen.

Das würde mich doch sehr wundern.
Ein
1
#define a 42
2
3
(...)
4
hallo(a);

wird ja schließlich auch nicht zu
1
h42llo(42);
 vermurkst, sondern wird zu
1
hallo(42);
 wie man es erwarten würde.

Ersetzung passiert nur, wenn eine komplette alphanumerische Zeichenkette 
erkannt wird, also durch Whitespace oder Zeichen wie Klammern etc. 
getrennt vom Rest. Nicht innerh42lb😉 eines Worts/Bezeichners.

von Rolf M. (rmagnus)


Lesenswert?

Frank M. schrieb:
> DerEinzigeBernd schrieb:
>> Macros aber sind #defines,
>
> Was soll das?

Die Frage müsste an dich gehen.

> Du weißt genau, was ich meine. Im Eröffnungsposting steht
> kein #define, nur etwas, was ein Aufruf eines Makros sein könnte,
> welches in einen Funktionsaufruf mündet - falls es nicht sogar direkt
> ein Funktionsaufruf ist.

Richtig. Damit wird auch klar, dass der TO mit "define" eben ein Makro 
meint, das er verwenden wollte und nicht die Präprozessor-Direktive 
selbst. Ich habe schon oft gesehen, dass Leute ein Makro als ein 
"define" bezeichnen.

> Konstruiere also bitte kein eventuelles Missverständnis.

Auch hier muss ich mich wundern, denn das scheinst du gerade zu tun. Du 
scheinst der einzige zu sein, der den Begriff "define" in der 
Überschrift anders versteht als er offensichtlich gemeint ist.

: Bearbeitet durch User
von FOp (Gast)


Lesenswert?

Ja, Asche auf mein Haupt, ich war auf dem Holzweg. Die Unterstriche 
dürfen in C in einem Token an beliebiger Stelle vorkommen.

Und nur komplette Tokens und nicht nur Teile davon werden vom 
Precompiler ersetzt.

Nachdenklicher hat mich da ja bereits treffend korrigiert.

Das Problem ist also, dass hier wohl jemand, der eher so was wie Python 
gewöhnt ist, ausführbaren Code ausserhalb jeglicher Funktion hingesetzt 
hat.

von DerEinzigeBernd (Gast)


Lesenswert?

FOp schrieb:
> Das Problem ist also, dass hier wohl jemand, der eher so was wie Python
> gewöhnt ist, ausführbaren Code ausserhalb jeglicher Funktion hingesetzt
> hat.

Das stand hier schon am 29.11.

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.