c++clangcompiler-warningsimplicit-conversionunsigned-integer

Clang gives me a warning of signedness change, however the code still produces correct output


I was analyzing some warnings in a codebase and got puzzled by this one generated by Clang

Consider the following C++ code:

#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 gives me the following warning when compiling this code with -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 also gives me this warning, however I need to provide -Wsign-conversion to trigger it.

The warning says that val2 will be cast to an unsigned int and therefore will loose it's sign. So far so good. However I was expecting that the code above would produce incorrect output, to my surprise it works perfectly fine.

Result is -10

See the program running on both compilers on godbolt.

The cast does not happen in the compiled code and val2 keep its original value. The result of the computation is correct. What is the actual danger that this warning is warning me against? How can I trigger this behaviour? Is the warning bogus?


Solution

  • What is the actual danger that this warning is warning me against?

    The potential danger is that you may have been unaware of the implicit sign conversion, and have made it by accident. If it is intentional and behaves as desired, then there is no danger).

    How can I trigger this behaviour?

    You already have triggered an implicit sign conversion.

    That said, if you want to see some output which may be surprising to you, try this instead:

    std::cout << val1 + val2;
    

    Is the warning bogus?

    Depends on your definition of bogus.

    There definitely is an implicit sign conversion in the program, and therefore if you ask the compiler to warn about implicit sign conversions, then it is entirely correct for the compiler to warn about the implicit sign conversion that is in the program.

    There is a reason why this warning option is not enabled by default, nor when enabling "all" warnings using -Wall, nor even when enabling "extra" warnings with -Wextra. These sign conversion warnings warn about a program with well defined behaviour, but which may be surprising to someone who is not paying close attention. A program can be meaningful and correct despite this warning.