Nulik
Nulik

Reputation: 7360

macro for dynamic types in C

When I define the macro like this:

    [niko@dev1 test]$ cat m1.c
    #define FL_UINT_FLINE_(N) typedef struct fl_uint_line_## N ##e { unsigned int        indexes[N]; } fl_uint_line_## N ##e_t;
    FL_UINT_FLINE_(4)
    FL_UINT_FLINE_(8)
    int main() {

        fl_uint_line_4e_t  fl4;
        fl_uint_line_8e_t  fl8;

    }
    [niko@dev1 test]$ 

it compiles perfectly. However I had to add the 'e' character ('e' for element) before and after the '## N ##' because without the 'e' I get a compile error:

[niko@dev1 test]$ cat m2.c
#define FL_UINT_FLINE_(N) typedef struct fl_uint_line_## N ## { unsigned int        indexes[N]; } fl_uint_line_## N ##_t;
FL_UINT_FLINE_(4)
FL_UINT_FLINE_(8)
int main() {

    fl_uint_line_4_t  fl4;
    fl_uint_line_8_t  fl8;

}
[niko@dev1 test]$ gcc -c m2.c
m2.c:1:42: error: pasting "fl_uint_line_4" and "{" does not give a valid preprocessing token
 #define FL_UINT_FLINE_(N) typedef struct fl_uint_line_## N ## { unsigned int        indexes[N]; } fl_uint_line_## N ##_t;
                                          ^
m2.c:2:1: note: in expansion of macro ‘FL_UINT_FLINE_’
 FL_UINT_FLINE_(4)
 ^
m2.c:1:42: error: pasting "fl_uint_line_8" and "{" does not give a valid preprocessing token
 #define FL_UINT_FLINE_(N) typedef struct fl_uint_line_## N ## { unsigned int        indexes[N]; } fl_uint_line_## N ##_t;
                                          ^
m2.c:3:1: note: in expansion of macro ‘FL_UINT_FLINE_’
 FL_UINT_FLINE_(8)
 ^
[niko@dev1 test]$ 

What is the correct syntax for macros in C, to make my type definitions look like this: (without the 'e'):

typedef struct fl_uint_line_4 { 
    unsigned int indexes[4]; 
} fl_uint_line_4_t;
typedef struct fl_uint_line_8 { 
    unsigned int indexes[8]; 
} fl_uint_line_8_t;

Upvotes: 2

Views: 512

Answers (1)

fuz
fuz

Reputation: 92986

I added a continuation line to your macro definition so it's easier to read:

#define FL_UINT_FLINE_(N) typedef struct fl_uint_line_## N ## { \
    unsigned int indexes[N]; } fl_uint_line_## N ##_t;

The ## operator concatenates two tokens to form a new token. Concatenating an identifier (what N expands to) and { yields something like foo{ which is not a valid token. Drop the second ## to fix this, it's not needed:

#define FL_UINT_FLINE_(N) typedef struct fl_uint_line_## N { \
    unsigned int indexes[N]; } fl_uint_line_## N ##_t;

Upvotes: 5

Related Questions