【问题标题】:technique for how to debug macros in C如何在 C 中调试宏的技术
【发布时间】:2011-01-01 15:15:07
【问题描述】:

所以我在程序的某处有(大部分被诽谤)#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 问题的数字太长,但我找不到它)。我想知道你们发现这些错误的技巧。

请注意,我并不是在寻求关于是否使用该宏的编程建议,我敢肯定人们很想告诉我我应该避免这样的事情,但问题在于其他地方。

谢谢。

【问题讨论】:

  • 能否请您用一些具有适当变量类型的代码更新它。通过仅查看提到的部分,我看不出宏有任何问题。你检查过预处理的代码吗?

标签: c debugging gcc ubuntu macros


【解决方案1】:

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

此代码是 Christian Charras and Thierry Lecroq 所述的 Boyer-Moore 字符串搜索吗?

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

【讨论】:

  • 谢谢,乔纳森。没错,是 Charras 等人的 BM。问题是,我似乎找不到会带来这个错误的“未签名”,两个数组都已签名,这让我想知道这个错误到底在哪里。当然,如果我使用函数而不是宏,那么整个事情就可以了。我想知道指向char 的指针是否正在做一些时髦的事情,但它被转换为int!因此问题。
  • @Dervin:你在哪个平台上?普通的char 值是有符号还是无符号?
【解决方案2】:

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

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

【讨论】:

  • MS VC 等价于 /P
  • 更正:stdout上的预处理器输出带有'/E','/P'用于指定文件名。
  • 或者你可以使用-g3,gdb 会知道宏:stackoverflow.com/a/2934061/309483
【解决方案3】:

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

无论如何,这段代码看起来很可疑。索引数组,例如您的 y[],您必须将其从 char 转换为 int 弱类型设计的味道。在不考虑可能的签名问题的情况下使用char 进行索引是很危险的。索引类型应始终为无符号类型。

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

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

clang 作为编译器非常适合调试宏。除了 gcc,例如,他能够跟踪宏的扩展,并且有时能够将您的鼻子放在有问题的宏扩展上。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-11
    • 2011-09-02
    • 1970-01-01
    • 2012-07-09
    • 2010-10-14
    • 2017-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多