Forum: PC-Programmierung C: too many arguments for macro


von Pascal (Gast)


Lesenswert?

Hallo,

ich compiliere ein Projekt für einen Freescale HCS12 mit einem 
Cosmic-Compiler. Im header-file module1.h steht folgendes:
1
#ifdef MODULE1_FILE_IDENT_C
2
    #define XMOD_EXTERN
3
    #define XMOD_INIT(initVal) = initVal
4
#else
5
    #define XMOD_EXTERN extern
6
    #define XMOD_INIT(initVal)
7
#endif

Im C-File module1.c existiert das #define MODULE_FILE_IDENT_C, welches 
dafür sorgt, dass die Variablen aus der module1.h nur in diesem 
Sourcefile angelegt und initialisiert werden. In anderen Sourcefiles, 
die die module1.h ebenfalls inkludieren, sollen die Variablen als extern 
deklariert werden.

Die module1.h legt das folgende Array an:
1
XMOD_EXTERN uint16_T TEST_ARRAY[12] XMOD_INIT({0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2});

Beim compilieren erhalte ich für die obige Zeile die Fehlermeldung "too 
many arguments for macro XMOD_INIT". Eigentlich sollte der Präprozessor 
nur suchen und ersetzen. Die Kommata in dem Array sollte er dabei doch 
gar nicht mitbekommen. Als Workaround habe ich die Initialisierung durch 
ein define ersetzt, was ohne Fehler compilierte.
1
#define INIT_TEST_ARRAY {0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8}
2
XMOD_EXTERN uint16_T TEST_ARRAY[12] XMOD_INIT(INIT_TEST_ARRAY);

Hat jemand eine Idee, wie man ein Macro realisieren kann ohne auf dieses 
IMO überflüssige define ausweichen zu müssen?

Danke für die Aufmerksamkeit!

von mar IO (Gast)


Lesenswert?

Zu deinem Problem habe ich keine Lösung, aber ich glaube das brauchst Du 
auch gar nicht (weiß nicht zu 100% was Du damit erreichen möchtest und 
wieso).

Außerdem wird mit deinen Defines der Code unleserlich und was spricht 
gegen (wenn man sowas überhaupt braucht):
1
#ifdef MODULE1_FILE_IDENT_C
2
    uint16_T TestArray[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2};
3
#else
4
    extern uint16_T TestArry[12];
5
#endif

von Yalu X. (yalu) (Moderator)


Lesenswert?

Normalerweise gilt die Regel: Deklarationen ins .h-File, Definitionen
ins .c-File. Hältst du dich daran, brauchst du nicht einmal eine
Fallunterscheidung, geschweige denn irgendwelche Makros:

irgendwas.h:
1
extern uint16_t TestArry[12];
2
//...

irgendwas.c:
1
#include "irgendwas.h"
2
//...
3
uint16_t TestArray[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2};

wasanderes.c:
1
#include "irgendwas.h"
2
//...
3
// Zugriffe auf TestArray

Die Definition exisitiert nur in einem einzigen .c-File, nämlich
irgendwas.c. Das Headerfile irgendwas.h mit der Deklaration kann in
beliebig vielen .c-Files, u.a. auch in irgendwas.c, eingebunden werden.

Das ist der normale Weg, wie es fast jeder macht.

Edit:

Zu deiner Frage, warum das Makro nicht funktioniert: Nur runde Klammern
klammern Kommata in Makroargumenten. Geschweifte Klammern hingegen sind
für den Präprozessor ganz normale Zeichen. Der Aufruf
1
XMOD_INIT({0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2})

hat also 12 Argumente, der erste davon ist "{0", der zweite "1" und der
letzte "2}" (jeweils ohne die Anführungszeichen). Deswegen erscheint die
Fehlermeldung.

von Mark .. (mork)


Lesenswert?

BTW, es gibt auch Variadic Macros, z.B.
1
#define XMOD_INIT(...)  = __VA_ARGS__

MfG Mark

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.