C++:需要警告:unsigned int i = -1;

11

我们的代码出现了一个bug,来自这一行:

unsigned int i = -1;
当代码最初编写时,它是i = 0,因此是正确的。使用-Wall -Wextra,我有点惊讶,因为-1无法适应无符号整数。
只有当开启-Wsign-conversion时,这行才会成为一个警告,但同时也会有很多错误的警告。 我正在使用第三方库进行类似数组的操作,其中包含有符号整数(虽然它们不能为< 0),所以每当我将其与例如向量混合时,我都会得到警告。而且我不认为在这里添加数百万个强制转换是有意义的(即使第三方头文件还会产生大量警告)。 所以对我来说这涉及太多的警告了。所有这些警告都是指这种转换“可能会改变符号”。这没关系,因为我知道在几乎所有情况下都不会改变符号。
但是针对上面提到的赋值语句,我却得到了相同的“可能改变”警告。这难道不应该是“一定会改变符号!”而不是“可能改变”的吗?是否有任何方法仅针对这些“一定会改变”的情况发出警告,而不是其他可能情况呢?

1
即使明确的符号更改通常是有意使用的。例如,std::string 具有 static const size_type npos = -1; - interjay
1
“-1” 在无符号类型中使用是有定义的,因此可以在程序中使用。 - Shafik Yaghmour
使用无符号类型来确保变量不会为负数是另一个错误 :D - Angelus Mortis
2
@AngelusMortis 不,这里要准确无误:使用“unsigned”确保数字不会为负数是行得通的,绝对是正确的做法。但它所不能做到的(请参见下面的答案)是防止负数的赋值和转换。但这些是不同的问题。 - Konrad Rudolph
2
@KonradRudolph 哎,我刚开始学习C++,只是想给人留下印象,其实我更像个白痴 :D - Angelus Mortis
我相信你已经遇到了 C 编程语言的另一个让步。在旧的 C 代码中,我经常遇到有符号和无符号值以及变量混合使用的情况。 - Richard Chambers
2个回答

5

使用花括号进行初始化:

unsigned int i{-1};

GCC输出:

main.cpp:3:22: 错误:在{ }内将'int'缩小为'unsigned int'
的'-1' [-Wnarrowing]
     unsigned int i{-1};

请注意,这并不总是会导致错误,它可能是一个警告或完全禁用的。你应该尝试使用你的实际工具链。


请提供编译标志以改善您的答案。 - YSC
1
它是格式不正确的,但不一定是错误 - Shafik Yaghmour
谢谢大家的见解,我已经修改了我的答案。 - Quentin
你可以使用 -Werror 命令在 gcc 和 clang 中将警告转换为错误。 - Shafik Yaghmour
我知道花括号不会缩小。但是=看起来更好,而且很多代码都是旧的。如果使用auto i = 0u;auto i = -1,这种情况也不会发生。 - Raubtier
显示剩余5条评论

1
但是,对于上面提到的赋值语句,我得到了相同的“可能会更改”的警告。这应该是“一定会更改符号!”而不是“可能会更改”吗?
奇怪的是,我测试了4.6-5.2范围内的几个版本的gcc,它们确实对“unsigned int i = -1;”给出了不同的警告。
负整数被隐式转换为无符号类型[-Wsign-conversion]的警告。
话虽如此,它们确实由与“可能更改符号”警告相同的选项控制,所以...
有没有办法仅在这些“将更改”的情况下发出警告,而不是在可能的情况下发出警告?
据我所知,这是不可能的。我相信编译器中可以实现这个功能,因此如果您想要一个单独的选项来启用警告,以便将已知在编译时分配负数值给无符号变量的情况,则可以提交功能请求。然而,因为将-1分配给无符号变量是一种常见且通常完全有效的操作,所以我怀疑这样的功能会被认为非常重要。

好的,谢谢你的回答。确实,警告文本是不同的。我只是在所有其他“可能”警告之间看错了一行。那么,似乎我的首选解决方案是使用更多的auto变量。 - Raubtier

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