我试图初始化数组,如下所示:
static tha_field_info_t person_t_fields[] = {
HA_FIELD_INFO(person_t, name, CHAR)
};
Run Code Online (Sandbox Code Playgroud)
相关数据结构:
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;
Run Code Online (Sandbox Code Playgroud)
使用的宏
#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)}
Run Code Online (Sandbox Code Playgroud)
使用此宏看到编译错误。
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)}
Run Code Online (Sandbox Code Playgroud)
但是,如果我像这样进行硬编码,则其工作正常。
{"name", CHAR, sizeof(((person_t *)0)->name), ((int)&((person_t *)0)->name)}
基本上,我想用结构person_t的字段信息存储数组。
小智 5
C中有两种类型的定义指令:
#define OBJECT_LIKE_MACRO followed by a "replacement list" of preprocessor tokens
#define FUNCTION_LIKE_MACRO(with, arguments) followed by a replacement list
Run Code Online (Sandbox Code Playgroud)
区分这两种类型的宏的是标记后的标识符#define:如果是lparen,则为类似函数的宏,否则为类似对象的宏。什么是lparen?N1570草案在附录A第3节中指出:
(6.10)LPAREN:
一个(字符不能立即通过空白前面
据我所知,这是C中少数几个重要的间隔之一(除了//注释,行拼接和预处理指令)。而且这很有道理。毕竟,预处理器如何区分任何函数式宏和具有以(令牌开头的替换列表的对象式宏?例如,以下是类似于对象的宏,而不是语法错误的类似于函数的宏:
#define NULL (void*)0
Run Code Online (Sandbox Code Playgroud)
现在让我们回答您的问题。问题出在这两行:
#define HA_FIELD_INFO (st, fname, dtype) \
{#fname, dtype, HA_FIELD_SIZE(st, fname), HA_FIELD_OFFSET(st, fname)}
Run Code Online (Sandbox Code Playgroud)
因为(after字符HA_FIELD_INFO是“以空格开头”,所以这不是您想要的类似函数的宏。只需删除该空间:
#define HA_FIELD_INFO(st, fname, dtype) \
{#fname, dtype, HA_FIELD_SIZE(st, fname), HA_FIELD_OFFSET(st, fname)}
Run Code Online (Sandbox Code Playgroud)