C 中的预处理器指令:使用 __LINE__ 的宏

Posted

技术标签:

【中文标题】C 中的预处理器指令:使用 __LINE__ 的宏【英文标题】:Preprocessor directives in C : macros using __LINE__ 【发布时间】:2015-05-08 07:16:48 【问题描述】:

我发现很难理解借助预处理器指令定义的宏的工作原理。

宏,

TRXEM_SPI_BEGIN()

是在两个头文件中引用的两个预处理器指令的帮助下定义的。首先,我想说明该宏的声明。

#define TRXEM_SPI_BEGIN() st( TRXEM_PORT_OUT &= ~TRXEM_SPI_SC_N_PIN; NOP();)

由于这里缺少宏st ()的声明,我发现它定义在不同的头文件中,ti如下所示。

#define st(x) do  x  while (__LINE__ == -1)

现在合并两个宏后,宏TRXEM_SPI_BEGIN()的真正定义一定是,

#define TRXEM_SPI_BEGIN() do 

( TRXEM_PORT_OUT &= ~TRXEM_SPI_SC_N_PIN; NOP(); )

 while (__LINE__ == -1)

编写此代码是为了在微控制器内部工作,其中TRXEM_PORT_OUTRXEM_SPI_SC_N_PIN 是内存映射寄存器,NOP 启动一个不执行任何操作的指令周期。

据我了解,__LINE__ 是指__LINE__ 所在的c 文件中的代码行。那条线永远不能等于-1。即此循环必须始终运行只运行一次,前提是永远不能将 __LINE__ 放在 -1 文件中的 .c 位置。简单地说,-1 永远不可能是__LINE__ 的值。

因此,我认为这里没有必要使用do while() 循环,并且只需不使用任何循环就可以实现相同的输出。

我不明白这个宏的功能。如果有人能详细说明,我将不胜感激。

【问题讨论】:

这些是(函数类型)宏或带有参数而非函数的宏。 do ... while (0) — what is it good for? 的可能重复项 好的,我将编辑问题。谢谢 @mohitJain 这个问题与您将其标记为重复的完全不同。 大概st() 的意思是“声明化”,即它把它的论点变成一个适当的 C 语句。使用__LINE == -1 而不仅仅是0 只是表明有人严重混淆了。这是一个错误,应该修复。 【参考方案1】:

根据我的理解,是指c文件中的代码行 __LINE__ 在哪里。那条线永远不能等于-1。即这个 循环必须始终只运行一次,前提是 __LINE__ 永远不会 放在 .c 文件中的 -1 位置。简单地说,-1 永远不可能是 将值返回到 __LINE__

您的理解在这里完全正确。它可以确保代码只运行一次。

考虑以下场景:

#define BAZ foo();bar();

如果你这样做了

if(some_cond) BAZ;

这相当于:

if(some_cond) foo();
bar();

这很可能不是你想要的。所以你把它改成:

#define BAZ foo();bar();

如果写成if(some_cond) foo() else wow();,这可以正常工作,但如果写成if(some_cond) foo(); else wow();,编译会失败

所以你定义BAZ

/* No semicolon at end */
#define BAZ do foo();bar(); while(condition_which_is_always_false)

您现在可以编写带有直观分号的自然代码。

在你的情况下,condition_which_is_always_false__LINE__ == -1

【讨论】:

谢谢@mohitJain。真心感谢你的努力。当我第一次研究您的参考资料时,它对我来说没有多大意义。现在它确实很有意义,非常感谢您的耐心。真的很感激。 如果有帮助我很高兴。您可能还会发现this 很有趣。

以上是关于C 中的预处理器指令:使用 __LINE__ 的宏的主要内容,如果未能解决你的问题,请参考以下文章

C标准中一些预定义的宏,如__FILE__,__func__等

C预处理器和C库

C++__LINE__宏的类型是啥

C语言便于调试的宏定义 __FILE____FUNCTION____LINE____VA_ARGS__ 参数使用

C++ 预处理器 __VA_ARGS__ 参数数量

#ifdef _CH_ 预处理器指令在 C 中做了啥?