传递整数文字时没有隐式转换警告?

use*_*113 4 c++ implicit-conversion

我试图了解隐式转换何时发生,并检测它们以提高代码库的质量。

我已经启用Wconversion,并Wsign-conversion为这个。但是我遇到了编译器没有给出任何错误的情况。例:

#include <iostream>
#include <array>

int main()
{
   std::array<int, 10> vec{};
   std::cout << vec[1] << std::endl; 
}
Run Code Online (Sandbox Code Playgroud)

编译:

$ g++ --std=c++14 -Wall -Wextra -Werror -pedantic -Wsign-conversion -Wconversion test.cpp 
$ 
Run Code Online (Sandbox Code Playgroud)

数组的大小和索引to operator[]都应为std::size_t(无符号)类型。但是,我正在传递带符号的文字,似乎没有问题。我什1.0F至可以传递给operator[]编译器。

operator[]但是,如果我为to的索引创建一个带符号的变量,则编译器会发出有关隐式转换的警告。

到底发生了什么事?使用文字时是否发生隐式转换?为什么编译器没有给出错误?我在Ubuntu 18.04上使用GCC 7.4。

Hol*_*olt 8

编译器不会警告您,因为它在编译时知道此转换是否安全,即原始值和目标值相同。当您这样做时:

vec[1.0F]
Run Code Online (Sandbox Code Playgroud)

从编译器的角度来看,1.0F和之间的值没有变化(精度损失)1,因此编译器不会警告您。如果你试试:

vec[1.2F]
Run Code Online (Sandbox Code Playgroud)

...编译器会警告您,因为即使1.2F将其转换为1,也会导致精度损失。

如果使用编译时未知的值,例如:

float get_float();

vec[get_float()];
Run Code Online (Sandbox Code Playgroud)

您将得到预期的警告,因为编译器get_float()事先不知道值,因此无法确定转换是安全的

请注意,当期望使用常量表达式时(例如in中std::array<int, 10>),您永远不会收到这样的警告,因为根据定义,常量表达式是在编译时已知的,因此编译器知道给定值和转换后的值之间是否存在问题。


Rei*_*ica 6

存在警告“将有符号转换为无符号”,因为其中某些转换可能会产生不良/意外的结果。将带1符号的转换为无符号的结果1没有任何问题。转换-3为无符号是有问题的。

使用变量,编译器不能(通常)知道运行时的值,因此必须警告潜在的转换问题。使用文字,它的值在编译时是已知的,因此编译器可以默默地做正确的事(当值转换为OK时),或在必要时发出警告/错误(当转换有问题时)。