Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No implicit conversion warnings when passing integer literals?

I'm trying to understand when implicit conversions happen and to detect them to improve the quality of my codebase.

I have enabled Wconversion and Wsign-conversion for this. However I came across a situation where the compiler doesn't give any error. Example:

#include <iostream>
#include <array>

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

Compiling:

$ g++ --std=c++14 -Wall -Wextra -Werror -pedantic -Wsign-conversion -Wconversion test.cpp 
$ 

Both the size of the array and the index to operator[] should be of type std::size_t (unsigned). However I'm passing signed literals and there seems to be no problem. I could even pass 1.0F to operator[] and the compiler would be fine.

If I create a signed variable for the index to operator[], however, then the compiler does warn about implicit conversion.

What's happening under the hood? Are implicit conversions happening when using literals? Why doesn't the compiler give an error? I'm using GCC 7.4 on Ubuntu 18.04.

like image 752
user1011113 Avatar asked Dec 07 '22 12:12

user1011113


1 Answers

The compiler does not warn you because it knows at compile time that this conversion if safe, i.e., the original and target value are identical. When you do:

vec[1.0F]

From a compiler point-of-view, there is no change of value (loss of precision) between 1.0F and 1, so the compiler does not warn you. If you try:

vec[1.2F]

...the compiler will warn you because, eventhough 1.2F will be converted to 1, there is a precision loss.

If you use a value that is not known at compile time, e.g.:

float get_float();

vec[get_float()];

You will get a warning as expected because the compiler does not know the value of get_float() beforehand and thus cannot be sure that the conversion is safe.

Note that you will never get such warning when constant expressions are expected (e.g., in std::array<int, 10>), because, by definition, constant expressions are known at compile time, so the compiler knows if there is an issue between the given value and the converted one.

like image 187
Holt Avatar answered Jan 18 '23 23:01

Holt