检测有符号和无符号比较错误

3

我在处理的一些代码中发现了一个问题,我担心这个问题可能存在于代码库的几个区域。这个问题与有符号/无符号比较有关:

unsigned short u16;
short s16;
u16 = 0x8000;
s16 = u16;
if (u16 > s16) {
    /* This is what gets printed in GCC */
    printf("u16 > s16\n");
} else if (u16 == s16) {
    printf("u16 == s16\n");
} else {
    printf("u16 < s16\n");
}

我理解为什么这是一个问题。您有没有可靠地定位代码库中此类问题的好方法?理想情况下,它应该出现为编译器警告或静态代码分析警告,但GCC和Coverity都没有发现任何问题。


如果你打开编译器的警告并使其详细,它是否会产生警告?还有一些静态工具可用。例如,寻找MISRA C合规软件工具。我不确定你是否愿意花钱。 - Makketronix
1
你有警告打开吗?GCC应该用-Wsign-compare-Wextra来警告这个问题。 - 0x5453
令人惊讶的是,这会警告您使用int,但不会警告您使用short。这在clang和gcc中都是正确的。 - Ryan Haining
关于:unsigned short u16; short s16; u16 = 0x8000; s16 = u16; 这正是编译器输出关于“有符号”和“无符号”变量之间相互作用的警告信息的原因。 - user3629249
@RyanHaining:并不太令人惊讶——整数提升意味着对于short类型会发生正确的(有符号)比较,而对于int类型会发生错误的(无符号)比较。 - Chris Dodd
1个回答

8
你可以使用-Wsign-compare-Wsign-conversion
第一个选项用于在比较有符号值和无符号值时发出警告。后一个选项则用于警告从无符号值到有符号值或从有符号值到无符号值的隐式转换。
在你的情况下,由于整数提升,-Wsign-compare 不会起作用,而 -Wsign-conversion 将会在 s16 = u16 的隐式转换中发出警告。

That's it. Thanks! - PaulH
1
当然,还有-Werror,只是为了确保你修复它们。 - pm100

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接