Re: UBSAN-safe way to convert from unsigned int to int

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



For what it's worth, C++20 defines this behavior:


   - If the destination type is signed, the value does not change if the
   source integer can be represented in the destination type. Otherwise the
   result is implementation-defined(until C++20)the unique value of the
   destination type equal to the source value modulo 2n
    where n is the number of bits used to represent the destination type(since
   C++20) (note that this is different from signed integer arithmetic
   overflow
   <https://en.cppreference.com/w/cpp/language/operator_arithmetic#Overflows>,
   which is undefined).


On Tue, May 20, 2025 at 9:45 AM David Brown via Gcc-help <
gcc-help@xxxxxxxxxxx> wrote:

> 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
>
>
>

-- 
Andrew Bell
andrew.bell.ia@xxxxxxxxx




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux