Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中带有#define的未定义行为_C_C Preprocessor_Undefined Behavior - Fatal编程技术网

C中带有#define的未定义行为

C中带有#define的未定义行为,c,c-preprocessor,undefined-behavior,C,C Preprocessor,Undefined Behavior,我在C中有一个定义,看起来像这样 #define ROW_SIZE ID_SIZE + USERNAME_SIZE + EMAIL_SIZE 估计为293 然后我做这个 uint32_t num_rows = pager->file_length / ROW_SIZE; pager->file\u length肯定是0 num_rows的结果是289。即使0/行大小也计算为289 为什么表达式的答案是错误的?宏扩展是基于令牌的替换。换句话说, pager->file_length

我在C中有一个定义,看起来像这样

#define ROW_SIZE ID_SIZE + USERNAME_SIZE + EMAIL_SIZE
估计为293 然后我做这个

uint32_t num_rows = pager->file_length / ROW_SIZE;
pager->file\u length
肯定是0
num_rows
的结果是289。即使
0/行大小
也计算为289


为什么表达式的答案是错误的?

宏扩展是基于令牌的替换。换句话说,

pager->file_length / ROW_SIZE
扩展到

pager->file_length / ID_SIZE + USERNAME_SIZE + EMAIL_SIZE
我相信您也同意,上述值不一定为零,尤其是当
USERNAME\u SIZE
EMAIL\u SIZE
不为零时

要解决此问题,请在宏定义中的表达式周围加括号:

#define ROW_SIZE (ID_SIZE + USERNAME_SIZE + EMAIL_SIZE)
发生了什么事

uint32_t num_rows = pager->file_length / ROW_SIZE;
扩展为

uint32_t num_rows = pager->file_length / ID_SIZE + USERNAME_SIZE + EMAIL_SIZE;
因此num_rows的计算结果为
0+ID_SIZE+USERNAME_SIZE+EMAIL_SIZE
,这不是零。考虑将括号添加到定义:

#define ROW_SIZE (ID_SIZE + USERNAME_SIZE + EMAIL_SIZE)

您必须记住,预处理器宏基本上是在源代码中被查询替换的

如果你有

uint32_t num_rows = pager->file_length / ROW_SIZE;
编译器在预处理后看到的是

uint32_t num_rows = pager->file_length / ID_SIZE + USERNAME_SIZE + EMAIL_SIZE;
由于法线等于

uint32_t num_rows = (pager->file_length / ID_SIZE) + USERNAME_SIZE + EMAIL_SIZE;
这当然不是你所期望或想要的。因此,在宏中始终使用额外的括号很重要,如

#define ROW_SIZE (ID_SIZE + USERNAME_SIZE + EMAIL_SIZE)

应该这样写:

#define ROW_SIZE (ID_SIZE + USERNAME_SIZE + EMAIL_SIZE)

#定义行大小ID\u大小+用户名大小+电子邮件大小
->
#定义(行大小ID\u大小+用户名大小+电子邮件大小)
这是一个非常常见的常见问题解答。任何初级C编程书籍都会在预处理器一章中解释如何编写正确的宏。它肯定会提到这个特定的错误,并带有操作符优先级和缺少正确的括号。那就去读那一章吧。有人知道这方面的经典复制品吗?我们需要一个!在定义一个macro@Lundin这个怎么样: