Forum: Mikrocontroller und Digitale Elektronik Präprozessor error


von Dennis (Gast)


Lesenswert?

Hallo zusammen,

Ich möchte folgende Präprozessor Anweisung anwenden
1
switch(channel)
2
      {
3
4
        case 6:    #ifdef __LOW_SIDE__
5
                   PORT1  &= ~(1<<OUT6);
6
                   #endif
7
8
                   #ifdef __HIGH_SIDE__
9
                   PORT1  |= (1<<OUT6);
10
                   #endif  
11
                   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) Benutzerseite


Lesenswert?

Vor dem "#" sollte in der Zeile nur Whitespace stehen.

von Dennis (Gast)


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)


Lesenswert?

doch, das ändert sehr wohl etwas:
1
switch(channel)
2
      {
3
4
        case 6:    // hier eine neue Zeile anfangen!!!!!!!!!!!!!!
5
                   #ifdef __LOW_SIDE__
6
                   PORT1  &= ~(1<<OUT6);
7
                   #endif
8
9
                   #ifdef __HIGH_SIDE__
10
                   PORT1  |= (1<<OUT6);
11
                   #endif  
12
                   break;

von Mark B. (markbrandis)


Lesenswert?

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

von Dennis (Gast)


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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)


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)


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


Lesenswert?

Bei meinen C-Anfängen (C&R) war das auch so. Einrückung durfte aber, 
soweit ich weiß, nach dem # erfolgen.
1
#ifdef ...
2
#  ifdef ..
3
..
4
#  endif
5
#endif

von Klaus W. (mfgkw)


Lesenswert?

K&R?

von Johann L. (gjlayde) Benutzerseite


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


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


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


Lesenswert?

Christian H. schrieb:
> Johann L. schrieb:
>> C&R = Christian & Ritchie
>
> "Kerningham & Ritchie"

Kernighan & Ritchie heißen die beiden.

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.