如何在C中调试宏的技术

时间:2011-01-01 15:15:08

标签: c debugging gcc ubuntu macros

所以我在一个程序中的某个地方(大多数被诽谤)#define MAX( a, b ) ( ((a) > (b)) ? (a) : (b) )(是的,是的,我知道)。在代码中的某个点上有一个比较X>-1?,其中X是(据我所知)一个(带符号)整数。该行为j += MAX(bmGs[i], bmBc[(int)y[i + j]] - m + 1 + i);,其中ychar*。不一定令人惊讶的是,我发现宏正在返回-1作为较大的数字(我猜测intunsigned问题的数字太长,但我找不到它)。我想知道你们可能有找到这些错误的技巧。

请注意,我不是在询问有关是否使用该宏的编程建议,我确信人们很想告诉我,我应该避免这样的事情,但问题是要去其他地方。

感谢。

3 个答案:

答案 0 :(得分:4)

我认为你的问题可能是标准C会通过将-1提升为无符号数量(保留值而不是符号保留)来比较有符号整数和无符号整数,这反过来意味着X永远不会更大而不是转换后的-1,并且比较始终为false。如果我是对的,宏是一个红鲱鱼;问题不在于宏本身(只要类型合理且两种参数都没有副作用,这是正确编写并且工作正常)。

此代码是否为Christian Charras and Thierry Lecroq

所描述的Boyer-Moore字符串搜索

如果bmGs是无符号的但是bmBc是有符号的,反之亦然,那么你就会遇到问题,但两个数组都是原始的有符号整数。

答案 1 :(得分:3)

如果您正在使用GCC,请使用“-E”(即 capital “E”)标志进行编译。这将只运行预处理器阶段,将输出发送到标准输出,然后停止。

这将让您了解如何评估您的宏。如果你真的想要 - 你可以把这个输出(重定向到一个文件,然后)修改文件并重新编译它 - 玩弄东西并尝试让它工作。

答案 2 :(得分:2)

我猜你的mi之一是size_t或类似的东西?然后,MAX宏的第二个arg也是size_t。也许它因此评估为(size_t)-1

无论如何,这段代码看起来很可疑。索引数组,例如您必须从y[]转换为char的{​​{1}}类型的索引数组。使用int进行索引而不考虑可能的签名问题是危险的。索引类型应始终为无符号类型。

char这样的宏,它隐含假设两个表达式具有相同的符号和宽度也是危险的。将其替换为函数MAX或类似的东西。

正确地重新设计类型,您的问题将自行解决。

作为编译器的

clang非常适合调试宏。除了gcc之外,他能够跟踪宏的扩展,并且有时能够让你的宏观扩展出现问题。