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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With