On 20/05/2025 12:13, Jonathan Wakely via Gcc-help wrote:
On Tue, 20 May 2025 at 10:59, Alexander Monakov via Gcc-help
<gcc-help@xxxxxxxxxxx> wrote:
On Tue, 20 May 2025, Florian Weimer via Gcc-help wrote:
Is there a concise way to convert X to a value Y of type int, so that
X == (unsigned int) Y
(assuming that X is of type unsigned int to start with)? GCC supports
this as an extension, using Y = (int) X, but this extension is
apparently unavailable if UBSAN is active.
Can you give a specific compilable example? Neither GCC nor Clang instruments
int f(unsigned x)
{
return x;
}
under -fsanitize=undefined.
Clang has -fsanitize=integer though:
int.cc:3:10: runtime error: implicit conversion from type 'unsigned
int' of value 2147483648 (32-bit, unsigned) to type 'int
' changed the value to -2147483648 (32-bit, signed)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior int.cc:3:10
GCC does not (and will not) implement that.
Converting an unsigned int to a signed int is not undefined behaviour.
If the original value cannot be represented in the signed int type (as
is the case here), then "either the result is implementation-defined or
an implementation-defined signal is raised". Stopping with a sanitiser
error could, I suppose, be considered as raising a signal - but it is
not UB.
The GCC manual explicitly says that conversion to signed types is done
modulo 2^n with no signals, so I think changing that behaviour would be
very problematic. I don't know what clang says about such things - if
indeed it does document such behaviour (as it should do).
If GCC wanted to add a way to re-interpret bits of a value of one type
as though it were another type, then perhaps __builtin_bit_cast could be
supported in C as well as C++. I would expect that (and the C++
function std::bit_cast<>) to do the conversion with optimal object code
and no run-time checking, regardless of any sanitiser flags. But that
would only help here if clang did the same.
David