Reputation: 1326
I am trying to initialize the array as follows :
static tha_field_info_t person_t_fields[] = {
HA_FIELD_INFO(person_t, name, CHAR)
};
Relevant Data structures:
typedef struct _tha_field_info_{
char fname[128];
DATA_TYPE_t dtype;
unsigned int size;
unsigned int offset;
} tha_field_info_t;
typedef struct _person{
char name[30];
unsigned int age;
} person_t;
Macros used
#define HA_FIELD_OFFSET(st, name) ((int)&((st *)0)->name)
#define HA_FIELD_SIZE(st, name) sizeof (((st *)0)->name)
#define HA_FIELD_INFO (st, fname, dtype) \
{#fname, dtype, HA_FIELD_SIZE(st, fname), HA_FIELD_OFFSET(st, fname)}
Seeing Compilation errors with this macros.
tha.h:35:28: error: ‘fname’ undeclared (first use in this function)
tha.h:35:35: error: ‘dtype’ undeclared (first use in this function)
tha.h:36:2: error: expected ‘}’ before ‘{’ token
{#fname, dtype, HA_FIELD_SIZE(st, fname), HA_FIELD_OFFSET(st, fname)}
tha.h:36:3: error: stray ‘#’ in program
{#fname, dtype, HA_FIELD_SIZE(st, fname), HA_FIELD_OFFSET(st, fname)}
However, If i Hardcode like this, then its work fine.
{"name", CHAR, sizeof(((person_t *)0)->name), ((int)&((person_t *)0)->name)}
Basically, i want to store the array with field information of structure person_t.
Upvotes: 3
Views: 494
Reputation:
There are two types of definition directives in C:
#define OBJECT_LIKE_MACRO followed by a "replacement list" of preprocessor tokens
#define FUNCTION_LIKE_MACRO(with, arguments) followed by a replacement list
What distinguishes these two types of macros is the token that follows the identifier after #define
: if it's an lparen, it is a function-like macro, and otherwise it's an object-like macro. What's an lparen? Draft N1570 points out in appendix A section 3:
(6.10) lparen:
a(
character not immediately preceded by white-space
As far as I know, this is one of the few cases in C where spacing matters (aside from //
comments, line splicing, and preprocessing directives). And it kind of makes sense. After all, how would the preprocessor distinguish between any function-like macro and an object-like macro that has a replacement list starting with a (
token? For instance, the following is an object-like macro, rather than a function-like macro with bad syntax:
#define NULL (void*)0
Let's now answer your question. The problem is in these two lines:
#define HA_FIELD_INFO (st, fname, dtype) \
{#fname, dtype, HA_FIELD_SIZE(st, fname), HA_FIELD_OFFSET(st, fname)}
Because the (
character after HA_FIELD_INFO
is "preceded by white-space", this is not the function-like macro that you intended it to be. Just remove that space:
#define HA_FIELD_INFO(st, fname, dtype) \
{#fname, dtype, HA_FIELD_SIZE(st, fname), HA_FIELD_OFFSET(st, fname)}
Upvotes: 5