Forum: Mikrocontroller und Digitale Elektronik Präprozessor error


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Dennis (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

Ich möchte folgende Präprozessor Anweisung anwenden
switch(channel)
      {

        case 6:    #ifdef __LOW_SIDE__
                   PORT1  &= ~(1<<OUT6);
                   #endif

                   #ifdef __HIGH_SIDE__
                   PORT1  |= (1<<OUT6);
                   #endif  
                   break;

Aber das gibt folgende Errors:

../manageOutputs.c:913: error: stray '#' in program
../manageOutputs.c:914: error: lvalue required as left operand of 
assignment
../manageOutputs.c:915:9: error: #endif without #if

Kann mir jemand sagen wo der Fehler liegt?

von Rufus Τ. F. (rufus) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Vor dem "#" sollte in der Zeile nur Whitespace stehen.

von Dennis (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Das ändert leidert auch nichts.

Es ist doch prinzipiell richtig dass nach #ifdef ein #endif kommt, ich 
verstehe nicht was für ein Problem der Compiler hier hat...?

von Klaus W. (mfgkw)


Bewertung
0 lesenswert
nicht lesenswert
doch, das ändert sehr wohl etwas:
switch(channel)
      {

        case 6:    // hier eine neue Zeile anfangen!!!!!!!!!!!!!!
                   #ifdef __LOW_SIDE__
                   PORT1  &= ~(1<<OUT6);
                   #endif

                   #ifdef __HIGH_SIDE__
                   PORT1  |= (1<<OUT6);
                   #endif  
                   break;

von Mark B. (markbrandis)


Bewertung
0 lesenswert
nicht lesenswert
Präprozessor-Direktiven gehören auf eine eigene Zeile, wie schon gesagt.

von Dennis (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Jetzt versteh ich, tatsächlich es geht. Der Grund ist mir ein Rätsel...

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
> Es ist doch prinzipiell richtig dass nach #ifdef ein #endif kommt
Es kann auch noch eine #else oder ein #elif dazwischenkommen  ;-)

von Sven P. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Dennis schrieb:
> Jetzt versteh ich, tatsächlich es geht. Der Grund ist mir ein Rätsel...

Das hat der Erfinder mal so festgelegt. War wohl einfacher zu 
implementieren.

von Karl H. (kbuchegg) (Moderator)


Bewertung
0 lesenswert
nicht lesenswert
Sven P. schrieb:
> Dennis schrieb:
>> Jetzt versteh ich, tatsächlich es geht. Der Grund ist mir ein Rätsel...
>
> Das hat der Erfinder mal so festgelegt. War wohl einfacher zu
> implementieren.

Wenn mein Gedächtnis nicht trügt, war es ursprünglich auch so, dass das 
# am Zeilenanfang stehen musste. Das wurde später dann gelockert, als 
Einrückungen in Mode kamen.

von Christian H. (netzwanze) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Bei meinen C-Anfängen (C&R) war das auch so. Einrückung durfte aber, 
soweit ich weiß, nach dem # erfolgen.
#ifdef ...
#  ifdef ..
..
#  endif
#endif

von Klaus W. (mfgkw)


Bewertung
0 lesenswert
nicht lesenswert
K&R?

von Johann L. (gjlayde) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Christian H. schrieb:
> Bei meinen C-Anfängen (C&R) war das auch so. Einrückung durfte aber,
> soweit ich weiß, nach dem # erfolgen.

C&R = Christian & Ritchie

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


Bewertung
0 lesenswert
nicht lesenswert
Wenn man sich trotzdem angewöhnt, das Doppelkreuz immer an den
Anfang der Zeile zu schreiben (und die Einrückung ggf. zwischen
Doppelkreuz und Direktive), kann einem so ein Fehler gar nicht
mehr passieren.

Der Präprozessor (bzw. das Preprocessing, wie es jetzt im C-Standard
heißt, da es nicht notwendig ein separater Prozessor sein muss, wie
das ganz am Anfang der Fall war) arbeitet (als einziges in der ganzen
C-Syntax) zeilenorientiert.  Er liest dabei jeweils eine Zeile ein
(das ist eine logische Zeile, also backslash-newline-Fortsetzungen
werden alle miteinander verkettet) und gibt für jede eingelesene
Zeile eine (ggf. modifizierte) Zeile wieder aus.  Daraus resultiert
einerseits, dass alle seine Direktiven am Anfang der Zeile stehen
müssen (um zu sehen, ob in dieser Zeile eine Direktive definiert
wird, muss er also nur von vorn beginnend ein Doppelkreuz suchen,
mittlerweile ggf. dabei Leerzeichen am Anfang überspringen), anderer-
seits folgt daraus auch, dass C-Programme immer aus kompletten Zeilen
aufgebaut sein müssen, die durch ein Zeilenendezeichen gemäß den
Definitionen des Hosts (LF, CR-LF, CR, was auch immer) abgeschlossen
ist.  Wenn die letzte Zeile des Programms nicht mit einem Zeilenende-
zeichen beendet ist, entsteht meiner Erinnerung nach undefiniertes
Verhalten.  Das ist auch erklärlich: es gestattet eine Implementierung
des Präprozessors, die die Verarbeitung der Zeile bis zum Auftreten
des Endezeichens verzögert.  Eine nicht beendete Zeile würde in diesem
Falle ,,im Präprozessor stecken bleiben'', also nie zum eigentlichen
Compiler weiter gereicht.

von Christian H. (netzwanze) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Johann L. schrieb:
> C&R = Christian & Ritchie

"Kerningham & Ritchie", sorry war ein Vertipper (bzw dachte er schreibt 
sich "Cerningham").

von Simon K. (simon) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Christian H. schrieb:
> Johann L. schrieb:
>> C&R = Christian & Ritchie
>
> "Kerningham & Ritchie"

Kernighan & Ritchie heißen die beiden.

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.