g++可以在将负字面量作为无符号参数传递时发出警告吗?

6

请考虑以下内容:

unsigned foo(unsigned u) {
    return u;
}

int main() {
    foo(-1);
    return 0;
}

在这里,函数foo被调用时,u等于4294967295(或类似的大值)。如果程序员没有注意到这一点,可能会出现意外情况。
例如,也许您正在实现pow来将多项式类提高到幂。由于只有正幂是可能的,因此您决定采用以下签名。
Polynomial pow(const Polynomial& p, unsigned exp);

然后,一个不小心的程序员调用 pow(p, -1) 来获取逆,而不是出现警告或错误,它似乎可以工作,但可能会使用极大的内存和时间来生成完全错误的答案。
g++ 5.3.0 和 gcc 5.3.0 使用 -Wall -Wextra 编译此代码而没有任何投诉。
使用选项 -Wsign-conversion 将发出警告,但这会警告每个从 int 转换为 unsigned 的转换,这很快就变得太烦人了(例如,每次使用 int 索引到向量中,vec[i],都会发出警告)。
gcc 可以仅警告将负文字面常量或其他负编译时常量用作无符号参数吗?

1
顺便说一句,具有讽刺意味的是,pow函数接受浮点参数而不是整数。 - Thomas Matthews
为了让我的第一个评论更具体:只需使用 Polynomial pow(const Polynomial& p, int exp); 并断言 exp 是正数(或非负数,任何一种都可以)。 - Baum mit Augen
pow()在处理负数幂时没有问题。唯一的限制是,如果底数为负数 指数为负数,则指数必须是整数值。 - vacuumhead
@vacuumhead:不适用于多项式。 - Nick Matteo
1
细节:由于此帖标记为C,因此在C中没有“负字面量” - 只有“字符串字面量”和“复合字面量”。存在具有负值的“整数常量”。 - chux - Reinstate Monica
显示剩余4条评论
1个回答

0

-Wconversion选项会警告您传递参数时的隐式转换。如果想将此警告视为错误,请添加-Werror选项。

以下是我的测试和其结果。

源代码文件temp.c:

unsigned foo(unsigned u) {
    return u;
}

int main() {
  foo(-1);
}

编译过程,

$ gcc -o temp temp.c -Wconversion
temp.c: In function ‘main’:
temp.c:6:7: warning: negative integer implicitly converted to unsigned type [-Wsign-conversion]
   foo(-1);
       ^

如果你将参数改为1,然后重新编译,警告就会消失。

(顺便说一句,始终使用-Wall是个好主意)。


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