Clang给了我一个签名变更的警告,但是代码仍然产生了正确的输出。

问题描述 投票:0回答:1

我在分析一个代码库中的一些警告时,被Clang生成的这个警告弄得一头雾水。

考虑以下C++代码。

#include <iostream>

int main(int , char *[])
{

  uint32_t val1 = 10;
  int32_t val2 = -20;

  int32_t result = val1 + val2;
  std::cout << "Result is " << result << "\n";

  return 0;
}

当我在编译这段代码时,Clang给了我以下警告 -Wconversion

<source>:9:25: warning: implicit conversion changes signedness: 
'unsigned int' to 'int32_t' (aka 'int') [-Wsign-conversion]

  int32_t result = val1 + val2;

          ~~~~~~   ~~~~~^~~~~~
<source>:9:27: warning: implicit conversion changes signedness: 
'int32_t' (aka 'int') to 'unsigned int' [-Wsign-conversion]

  int32_t result = val1 + val2;

                        ~ ^~~~
2 warnings generated.

GCC也给我这个警告,但是我需要提供 -Wsign-conversion 来触发它。

警告说 val2 将被投向 unsigned int 因此会失去它的招牌。到目前为止,一切都很好。但我希望上面的代码能产生出 输出,令我惊讶的是,它的工作完全正常。

Result is -10

请看在两个编译器上运行的程序 在戈壁上.

在编译后的代码中不会发生这种情况,而且...。val2 保持其原始值。计算的结果是正确的。什么是 实际 这个警告所警告我的危险?我如何才能触发这种行为?这个警告是假的吗?

c++ clang compiler-warnings implicit-conversion unsigned-integer
1个回答
1
投票

这个警告实际是在警告我什么危险呢?

潜在的危险是,你可能没有意识到隐式符号转换,而不小心做了这个转换。如果是故意的,并且行为如愿,那么就没有危险)。)

如何触发这种行为?

你已经触发了隐式符号转换。

也就是说,如果你想看到一些可能让你感到惊讶的输出,可以试试这个。

std::cout << val1 + val2;

这个警告是假的吗?

取决于你对虚假的定义。

程序中肯定存在隐式符号转换,因此如果你要求编译器对隐式符号转换进行警告,那么编译器对程序中存在的隐式符号转换进行警告是完全正确的。

为什么默认情况下不启用这个警告选项,在使用-Wall启用 "所有 "警告时也不启用,甚至在使用-Wextra启用 "额外 "警告时也不启用,这是有原因的。这些符号转换警告会警告一个有明确行为的程序,但对于没有密切注意的人来说,可能是令人惊讶的。尽管有这个警告,一个程序仍然可以是有意义的和正确的。


3
投票

符号转换警告 第二 转换的地方,事情变得依赖于实现。

第一个(表达式的评估 val1+val2)触发转换 val2 从 signed 到 unsigned,这是符合标准的,也是有文档可查的。因此,表达式的结果是无符号的。

第二种(将产生的unsigned 后面 到signed类型)是潜在问题的地方。如果无符号值不在目标符号类型的定义域内(在这种情况下,它不是),那么实现行为就会随之而来,你不能假定它在已知宇宙中是可移植的。

© www.soinside.com 2019 - 2024. All rights reserved.