如何在 C 中调试宏的技术
所以我在程序中的某个地方有(大多数被诽谤的)#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
code> 问题,但我找不到它)。我想知道你们可能有发现此类错误的技术。
请注意,我并不是在寻求有关是否使用该宏的编程建议,我确信人们很想告诉我我应该避免这样做,但问题是在其他地方。
谢谢。
So I have the (mostly vilified) #define MAX( a, b ) ( ((a) > (b)) ? (a) : (b) )
somewhere in a program (yes, yes, I know). At some point in the code there is a comparison X>-1?
, where X is (as far as I can tell) a (signed) integer. The line is j += MAX(bmGs[i], bmBc[(int)y[i + j]] - m + 1 + i);
, where y
here is a char*
. Not necessarily surprisingly, I find that the macro is returning -1
as the larger number (I'm guessing too long a number for int
or an unsigned
issue, but I can't find it). I would like to know techniques you guys may have for finding these kinds of errors.
Notice that I'm not asking for programming advice about whether or not to use that macro, I'm sure folks are dying to tell me I should refrain from things like that, but the question is going somewhere else.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我猜你的
m
或i
之一是size_t
或类似的东西?那么MAX
宏的第二个参数也是size_t
。也许它的计算结果为(size_t)-1
?无论如何,这段代码看起来很可疑。索引数组,例如必须从
char
转换为int
的y[]
,有点弱类型设计的味道。使用char
建立索引而不考虑可能的符号问题是很危险的。索引类型应始终是无符号类型。像
MAX
这样的宏隐式假设两个表达式具有相同的符号和宽度也是危险的。将其替换为函数intmax_t MAX(intmax_t, intmax_t)
或类似的函数。正确地重新设计类型,您的问题就会自行解决。
clang 作为编译器非常适合调试宏。例如,除了 gcc 之外,他还能够跟踪宏的扩展,并且有时能够发现有问题的宏扩展。
I'd guess that one of your
m
ori
is asize_t
or something like that? Then the second arg of theMAX
macro issize_t
, too. Perhaps it thus evaluates to(size_t)-1
?In any case this code looks suspicious. Index arrays such as your
y[]
that you'd have to cast fromchar
toint
smell of a weak type design. Indexing withchar
without taking care of the possible signedness problems is just dangerous. Index types should always be unsigned types.A macro like your
MAX
that makes implicit assumptions that both expressions have the same signedness and width is also dangerous. Replace it with a functionintmax_t MAX(intmax_t, intmax_t)
or something like that.Redesign the types properly and your problem will solve itself.
clang as a compiler is quite good for debugging macros. Other than gcc e.g he is able to keep track of the expansion of macros and is sometimes able to put your nose on a problematic macro expansion.
我认为你的问题可能是标准 C 会通过将
-1
提升为无符号数量(保留值而不是符号保留)来比较有符号整数和无符号整数,这反过来意味着 X 永远不会大于转换后的-1
,并且比较始终为 false。如果我是对的,这个宏是一个转移注意力的东西;问题不在于宏本身(只要类型合理并且两个参数都没有副作用,宏就可以正确编写并且工作正常)。此代码是否为 Boyer-Moore 字符串搜索,如 Christian Charras 和蒂埃里·勒克罗克?
如果 bmGs 是无符号的,但 bmBc 是有符号的,反之亦然,则会遇到问题,但两个数组在原始数组中都是带符号的整数。
I think your problem may be that standard C will compare a signed integer and an unsigned integer by promoting
-1
to an unsigned quantity (value preserving instead of sign preserving), which in turn means that X is never greater than the converted-1
, and the comparison is always false. If I'm correct, the macro is a red herring; the problem is not the macro per se (which is written correctly and works fine as long as the types are sensible and neither argument has side effects).Is this code the Boyer-Moore string search, as described by Christian Charras and Thierry Lecroq?
If bmGs is unsigned but bmBc is signed or vice versa, you'd have problems, but both arrays are signed integers in the original.
如果您使用的是 GCC,请使用“-E”(即大写“E”)标志进行编译。这将仅运行预处理器阶段,将输出发送到标准输出,然后停止。
这将让您看到您的宏是如何被评估的。如果您确实想要 - 您可以获取此输出(然后将其重定向到文件)修改文件并重新编译它 - 进行尝试并尝试使其工作。
If you're using GCC, compile with the "-E" (that's capital "E") flag. This will run only the preprocessor stage, sending the output to standard output, then stop.
This will let you see how your macros are being evaluated. If you really want - you can take this output (redirect it to a file, then) modify the file and re-compile it - to play around with things and try to get it to work.