为何直接在for循环用TEST_DATA_ROWS宏报错,赋值变量却正常?
宏定义末尾分号导致的编译错误问题
代码定义
static const unsigned char test_bin[28800] = {0}; #define TEST_DATA_COLUMNS 2 #define TEST_DATA_ROWS (sizeof(test_bin)/sizeof(float)/TEST_DATA_COLUMNS); static const float (* test_data)[TEST_DATA_COLUMNS] = (const float (*)[TEST_DATA_COLUMNS]) test_bin;
错误场景
直接在for循环中使用TEST_DATA_ROWS会触发编译错误:error: expected expression before ';' token,对应代码:
for(size_t i = 0; i < TEST_DATA_ROWS ; i++);
正常场景
将宏赋值给变量后再使用则可正常编译:
size_t nrows = TEST_DATA_ROWS; for(size_t i = 0; i < nrows ; i++);
原因分析
问题根源在于TEST_DATA_ROWS的宏定义末尾多了一个分号;。宏是纯文本替换,不会做语法校验:
- 当在for循环条件中使用时,预处理器会把
i < TEST_DATA_ROWS替换为i < (sizeof(test_bin)/sizeof(float)/TEST_DATA_COLUMNS);,这就导致for循环的条件部分多出一个分号,破坏了for(初始化; 条件; 增量)的语法结构,编译器因此报错。 - 当赋值给变量时,
size_t nrows = TEST_DATA_ROWS;会被替换为size_t nrows = (sizeof(test_bin)/sizeof(float)/TEST_DATA_COLUMNS);;,这里的两个分号中,第一个是赋值语句的结束符,第二个是宏带来的多余分号,而C语言允许单独的分号作为空语句存在,编译器会忽略这个多余的空语句,因此代码可以正常编译运行。
解决方法
去掉宏定义末尾的分号即可:
#define TEST_DATA_ROWS (sizeof(test_bin)/sizeof(float)/TEST_DATA_COLUMNS)
内容的提问来源于stack exchange,提问作者xvan
相关产品推荐
相关产品推荐

