Forum: Mikrocontroller und Digitale Elektronik Böses enum in header


von Joachim .. (joachim_01)


Lesenswert?

Hab hiern Projekt das so aussieht:

in der Datei CAN18XX8.h:
1
enum CAN_RX_MSG_FLAGS
2
{    CAN_RX_RTR_FRAME    = 0b01000000,   // Set if RTR message else
3
     CAN_RX_DBL_BUFFERED = 0b10000000    // Set if this message was
4
5
}

ich hab eben das hier probiert:
1
enum CAN_RX_MSG_FLAGS
2
{    CAN_RX_RTR_FRAME    = 0b01000000,   // Set if RTR message else
3
     CAN_RX_DBL_BUFFERED = 0b10000000    // Set if this message was
4
5
}NewMessageFlags; // ergibt: Error: syntax error




in main.c:

#include "CAN18XX8.h"
1
void main (void) {
2
  CAN_RX_MSG_FLAGS NewMessageFlags;  //ebenfalls: Error: syntax error
3
 ...
4
 ...
5
}
Compiler ist mplabc18. Warum geht es nicht?
Ich hab's noch mit dem Schlüsselwort 'extern' rumgestochert, aber das 
ging auch nich.

: Verschoben durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

1
 enum CAN_RX_MSG_FLAGS NewMessageFlags;
Beachte, daß NewMessageFlags schon global definiert ist.

von Joachim .. (joachim_01)


Lesenswert?

>Beachte, daß NewMessageFlags schon global definiert ist.
Nee, es gehen ja beide Varianten nicht. In der zugehörigen CAN18XX8.c

1
CAN_RX_MSG_FLAGS NewMessageFlags;

funktionierts. Aber ich brauche es in der main-Funktion.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Joachim ... schrieb:
> Aber ich brauche es in der main-Funktion.

Dann schreib halt
1
extern enum CAN_RX_MSG_FLAGS NewMessageFlags;

in eine von main.c eingebundene Headerdatei.

Oder willst Du eine eigene, von der in can18xx8.c unabhängige Variable 
anlegen?

Dann nenn sie anders, und definiere sie so:
1
enum CAN_RX_MSG_FLAGS MyOwnNewMessageFlags;

von Joachim .. (joachim_01)


Lesenswert?

>Dann schreib halt
1
extern enum CAN_RX_MSG_FLAGS NewMessageFlags;
Treffer.


Ich hatte es zuerst so probiert:
1
extern CAN_RX_MSG_FLAGS NewMessageFlags;
Das ging nicht.


Danke an alle.

von Rene H. (Gast)


Lesenswert?

Gibt es einen Grund, dass man da kein typedef macht?
1
typedef enum CAN_RX_MSG_FLAGS
2
{    CAN_RX_RTR_FRAME    = 0b01000000,   // Set if RTR message else
3
     CAN_RX_DBL_BUFFERED = 0b10000000    // Set if this message was
4
5
};

und dann, dass so verwendet:
1
CAN_RX_MSG_FLAGS NewMessageFlags;

Grüsse,
René

von Karl (Gast)


Lesenswert?

Rene H. schrieb:
> Gibt es einen Grund, dass man da kein typedef macht?
> typedef enum CAN_RX_MSG_FLAGS
> {    CAN_RX_RTR_FRAME    = 0b01000000,   // Set if RTR message else
>      CAN_RX_DBL_BUFFERED = 0b10000000    // Set if this message was
>
> };

Ist durchaus üblich, aber die Syntax oben ist falsch.
Muss dann heissen:
1
typedef enum 
2
{
3
    /* Konstanten wie oben */
4
}   CAN_RX_MSG_FLAGS;
Gruss Karl

von Joachim .. (joachim_01)


Lesenswert?

>Gibt es einen Grund, dass man da kein typedef macht?
Weiss nicht. Der Code ist aus nem Example.
Jedenfalls stolpere ich regelmäßig über Deklarationen die ausserhalb 
einer Funktion liegen :-(

Ist
c]
enum CAN_RX_MSG_FLAGS
{    CAN_RX_RTR_FRAME    = 0b01000000,   // Set if RTR message else
     CAN_RX_DBL_BUFFERED = 0b10000000    // Set if this message was

}
[/c]
schon eine Definition oder noch eine Deklaration? Ich vermute mal 
ersteres.

von Rene H. (Gast)


Lesenswert?

Karl schrieb:
> Ist durchaus üblich, aber die Syntax oben ist falsch.
> Muss dann heissen:

Natürlich, sorry. Man sollte nicht kochen und nebenbei Tippen.

Grüsse,
R.

von Rene H. (Gast)


Lesenswert?

Ein typedef ist eine Deklaration. Eine Definition in einer C-Headerdatei 
sollte man wenn möglich vermeiden.

Oder anders gesagt, extern ist böse. Wenn auch immer machbar, unbedingt 
vermeiden.

Grüsse,
R.

von Karl H. (kbuchegg)


Lesenswert?

Joachim ... schrieb:
>>Gibt es einen Grund, dass man da kein typedef macht?
> Weiss nicht. Der Code ist aus nem Example.
> Jedenfalls stolpere ich regelmäßig über Deklarationen die ausserhalb
> einer Funktion liegen :-(
>
> Ist
> c]
> enum CAN_RX_MSG_FLAGS
> {    CAN_RX_RTR_FRAME    = 0b01000000,   // Set if RTR message else
>      CAN_RX_DBL_BUFFERED = 0b10000000    // Set if this message was
>
> }
> [/c]
> schon eine Definition oder noch eine Deklaration? Ich vermute mal
> ersteres.

Deklaration.

Aber der springende Punkt ist ein ganz anderer.
Auch bei einem enum gilt, dass der Name des enum nicht automatisch der 
Name eines neuen Datentyps ist. Also völlig analog zu einem struct oder 
einer union.
Daher muss das Schlüsselwort 'enum' bei der eigentlichen Definition von 
Variablen mit angeführt werden.
1
enum irgendwas
2
{
3
  erster,
4
  zweites
5
};
6
7
// und jetzt wird eine Variable vom Datentyp 'enum irgendwas' angelegt
8
enum irgendwas meineVar;

Der Datentyp der Variablen lautet 'enum irgendwas' und nicht einfach nur 
'irgendwas'

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz Buchegger schrieb:

>> schon eine Definition oder noch eine Deklaration? Ich vermute mal
>> ersteres.
>
> Deklaration.

ALs Faustregel kannst du dir merken:
Alles, wofür der Compiler im fertigen Exe Speicher reservieren muss, ist 
eine Defintion.
Ansonsten ist es eine Deklaration - etwas das dem Compiler zur 
gefälligen Kenntnisnahme präsentiert wird und was er sich einfach nur 
merken soll, bis es irgendwo benutzt wird.

Muss der Compiler für
1
enum xyz
2
{
3
  a, b
4
};
irgendwas im Code anlegen?
Nein.
Er trägt sich in seinen internen Tabellen ein, dass es einen enum gibt, 
wie er heißt und welche Wertnamen und Werte er umfasst und das wars. 
Mehr hat der Compiler damit nicht zu tun.

Daher: Deklaration

Was anderes ist es, wenn du dann tatsächlich eine Variable erzeugst
1
enum xyz meinXyz;
jetzt muss der Compiler dafür sorgen, dass im fertigen Programm auch 
tatsächlich Speicher für diese Variable bereitgestellt wird. Daher: 
Definition.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz Buchegger schrieb:

> Der Datentyp der Variablen lautet 'enum irgendwas' und nicht einfach nur
> 'irgendwas'

Und um das weiterzuspielen.
Genau an diesem Punkt kommt dann der typedef ins Spiel.
Ein typedef vereinbart einen anderen Namen für einen Datentyp.

Damit man sich die Syntax eines typedef leicht merken kann, sieht sie 
aus wie die Definition einer Variablen. Nur mit dem Schlüsselwort 
typedef davor. Der 'Name' der Variablen wird dann zum Namen dieses neuen 
Datentyps.

Wie würde man eine Variabl vom Datentyp 'enum irgendwas' definieren?
So
1
enum irgendwas meineVar;

mach ein typedef davor
1
typedef enum irgendwas NameEnum;

und 'NameEnum' ist dann ein anderer Name für den Datentyp 'enum 
irgendwas'. Ergo kann man dann damit neue Variablen definieren
1
NameEnum meineVar;

meineVar ist eine Variable vom Datentyp 'NameEnum' und 'NameEnum' ist 
nichts anderes als ein anderer Name für den Datentyp 'enum irgendwas'.

Sinn der Sache ist es, dass man sich die Tippslerei des ewig gleichen 
'enum' bei Variablen, Funktionsargumenten, etc. etc. erspart.

von Joachim .. (joachim_01)


Lesenswert?

>Ansonsten ist es eine Deklaration - etwas das dem Compiler zur
>gefälligen Kenntnisnahme präsentiert wird und was er sich einfach nur
>merken soll, bis es irgendwo benutzt wird.
Sehr schön, den Satz kann auch ich mir gut merken.


Ich schreib immer nur alle paar Monate n paar Zeilen fürn kleines 
Projekt, dadurch verschussel ich im Gedächtnis manchmal die 
Grundlagen...
Bin halt nur 'n Löter;-)

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.