所以我在一个程序中的某个地方(大多数被诽谤)#define MAX( a, b ) ( ((a) > (b)) ? (a) : (b) )
(是的,是的,我知道)。在代码中的某个点上有一个比较X>-1?
,其中X是(据我所知)一个(带符号)整数。该行为j += MAX(bmGs[i], bmBc[(int)y[i + j]] - m + 1 + i);
,其中y
为char*
。不一定令人惊讶的是,我发现宏正在返回-1
作为较大的数字(我猜测int
或unsigned
问题的数字太长,但我找不到它)。我想知道你们可能有找到这些错误的技巧。
请注意,我不是在询问有关是否使用该宏的编程建议,我确信人们很想告诉我,我应该避免这样的事情,但问题是要去其他地方。
感谢。
答案 0 :(得分:4)
我认为你的问题可能是标准C会通过将-1
提升为无符号数量(保留值而不是符号保留)来比较有符号整数和无符号整数,这反过来意味着X永远不会更大而不是转换后的-1
,并且比较始终为false。如果我是对的,宏是一个红鲱鱼;问题不在于宏本身(只要类型合理且两种参数都没有副作用,这是正确编写并且工作正常)。
此代码是否为Christian Charras and Thierry Lecroq?
所描述的Boyer-Moore字符串搜索如果bmGs是无符号的但是bmBc是有符号的,反之亦然,那么你就会遇到问题,但两个数组都是原始的有符号整数。
答案 1 :(得分:3)
如果您正在使用GCC,请使用“-E”(即 capital “E”)标志进行编译。这将只运行预处理器阶段,将输出发送到标准输出,然后停止。
这将让您了解如何评估您的宏。如果你真的想要 - 你可以把这个输出(重定向到一个文件,然后)修改文件并重新编译它 - 玩弄东西并尝试让它工作。
答案 2 :(得分:2)
我猜你的m
或i
之一是size_t
或类似的东西?然后,MAX
宏的第二个arg也是size_t
。也许它因此评估为(size_t)-1
?
无论如何,这段代码看起来很可疑。索引数组,例如您必须从y[]
转换为char
的{{1}}类型的索引数组。使用int
进行索引而不考虑可能的签名问题是危险的。索引类型应始终为无符号类型。
像char
这样的宏,它隐含假设两个表达式具有相同的符号和宽度也是危险的。将其替换为函数MAX
或类似的东西。
正确地重新设计类型,您的问题将自行解决。
作为编译器的clang非常适合调试宏。除了gcc之外,他能够跟踪宏的扩展,并且有时能够让你的宏观扩展出现问题。