Consider
U8 foo(U8 x, U8 y) {
return x % y;
}
GCC's -Wconversion behaves differently if U8, the type of x and y, is char or unsigned char:
gcc -Wconversion -c test.c -DU8='unsigned char'
(no warning)
gcc -Wconversion -c test.c -DU8=char
test.c: In function ‘foo’:
test.c:2:14: warning: conversion to ‘char’ from ‘int’ may alter its value [-Wconversion]
return x % y;
~~^~~
But from what I understand in both cases x, y undergo integer promotion (to int or unsigned int) and so in both cases it will be converting from int to whatever the return type is (char or unsigned char).
Why is there a difference?
Bonus question: if you enable ubsan (-fsanitize=undefined) then GCC emits -Wconversion in both cases.
EDIT:
There is no argument that x, y undergo integer promotion and then need to be converted to the result type, so no need to explain that.
The only question here is why does GCC behave differently for different types. The answer will involve some insight on GCC's internals.
intconverted to achar, and anintcan hold larger values than achar. So GCC warns. - Prof. Falken/rounds towards zero, and%is forced to follow the suit. E.g.-5 % 2 = -1- AnT%isreminder operatorin c notmodulus, so the sign is the same of the dividend. - LPs