Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Warnings on sign conversion when assigning from the result of unsigned division

Tags:

c++

clang++

I compiled the following code with -Wsign-conversion :

int main() 
{
  unsigned int a = 8;
  int b = a + 8u;  // warning: implicit conversion changes signedness: 'unsigned int' to 'int'
  int c = a - 8u;  // warning: implicit conversion changes signedness: 'unsigned int' to 'int'
  int d = a * 8u;  // warning: implicit conversion changes signedness: 'unsigned int' to 'int'
  int e = a / 8u;  // gcc warns, but no warning in clang
}

Clang doesn't emit a warning when assigning from the result of an unsigned division, but gcc does.

Why is there a difference in this one particular case?

like image 282
Ofek Shilon Avatar asked Sep 01 '25 21:09

Ofek Shilon


1 Answers

Clang is just being an extra bit clever: division of an unsigned integer by an unsigned integer larger or equal to 2 means the unsigned integer result will always fit in the signed integer counterpart (to that of the numerator type in the division expression). However, if you divide by an unsigned integer valued 1, the result is no longer guaranteed to fit in a signed integer counterpart, and Clang does emit a warning:

#include <cstdint>

int main()  {
  uint8_t a = 240;    // '240 / 1' will not fit in int8_t
  int8_t e = a / 2u;  // No warning in clang
  int8_t f = a / 1u;  // warning: implicit conversion changes signedness: 'unsigned int' to 'int8_t' (aka 'signed char') [-Wsign-conversion]
}

One could also argue that Clang should be able to omit the warning for the similar special case of multiplication by 0; however Clang does not whereas GCC, instead, does:

// Clang warns, no warning in GCC.
int8_t g = a * 0u;

So peculiarly Clang is clever, in this context, w.r.t. division and GCC w.r.t. multiplication.


Finally, note that the gating for Clang to emit this warning during division seems to be only when dividing by 1, as you will not get the same -Wsign-conversion if you divide by 0u; arguably as it has been overridden by the more relevant (in such a context) -Wdivision-by-zero warning:

int8_t h = a / 0u;
warning: division by zero is undefined [-Wdivision-by-zero]
like image 138
dfrib Avatar answered Sep 03 '25 10:09

dfrib



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!