gpt4 book ai didi

c - 如何使用一个操作数不执行任何操作的三元运算符创建#define 宏?

转载 作者:行者123 更新时间:2023-12-02 04:42:22 25 4
gpt4 key购买 nike

我正在阅读“没有错误!”由 David Thielen 撰写,第 3 章讨论了一种确定是否已命中给定代码路径的方法。它建议使用一个宏来检查参数,如果为真,则执行生成特定中断 (0x3) 的汇编指令以创建调试器断点。如果宏的参数为假,它什么都不做。

宏看起来像这样:

#ifdef DEBUG
#define Trap(t) ( (t) ? __asm__("int $0x3") : )
#endif

然而,这段代码会导致 gcc 的编译错误:

int_test.c:16:35: error: expected expression before ‘__asm__’

我从here中学到了因为 gcc 的 asm 是 block 语句而不是表达式,所以我必须使用 statement expressions为了以这种方式使用asm。所以,现在它变成了:

#define Trap(t)     ( (t) ? ({ __asm__("int $0x3"); }) : )

编译器仍然报错:

int_test.c:16:64: error: expected expression before ‘)’ token

好的,那么现在我必须这样做吗?

#define Trap(t)     ( (t) ? ({ __asm__("int $0x3"); }) : ({ ; }) )

这看起来真的很愚蠢。如果 t 为假,我不能不使用这种烦人的语法就让预处理器不插入任何内容吗?

注意:为了简单起见,我省略了一些其他类似的宏,并且我已经改编了书中的语法以适用于 gcc(例如将书中的 _asm 替换为 asm 以及使用 AT&T "") 中的语法和周围的程序集

最佳答案

您从本书中获得的建议主要是创建您自己的 assert() 功能。

在大多数系统上,您应该只使用 assert.h 中提供的 assert() 宏。如果断言被触发并且您在调试器下运行,断言将触发断点(同样 - 在大多数系统上)。

如果由于某种原因你不能使用标准的 assert.h 功能(例如,可能是某种不提供它的准系统嵌入式系统工具链),你可以这样做类似于以下内容:

#ifdef DEBUG_MODE
void DoAssert(void);
#define ASSERT(expr) ((expr) ? (void) 0 : DoAssert())
#else
#define ASSERT(expr) ((void) 0)
#endif

然后将您需要的任何内容放入 DoAssert() 函数中的调试器中 - 在您的情况下,这将是 int 3 的内联汇编。

关于c - 如何使用一个操作数不执行任何操作的三元运算符创建#define 宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20577065/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com