https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115695

Julian Gompper <juliangmp at protonmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |juliangmp at protonmail dot com

--- Comment #2 from Julian Gompper <juliangmp at protonmail dot com> ---
I ran into this by just using -Wsign-conversion (with g++ (Debian 10.2.1-6)
10.2.1 as well as (Debian 12.2.0-14) 12.2.0).
Though strangely, I only get the warning when I have the cast in the argument
of the function call, but it's completely fine when I store the cast value as a
variable.

```
void do_something(unsigned long long val) { }

int main() {
    short int input_val = 1234;

    // passing the value directly, will cause a Wsign-conversion
    do_something(static_cast<uint64_t>(input_val));

    // storing the uint64_t as a variable will compile without a warning
    const uint64_t converted_val = static_cast<uint64_t>(input_val);
    do_something(converted_val);
}
```

The warning text for reference:
test.cpp:11:18: warning: conversion to ‘long long unsigned int’ from ‘uint64_t’
{aka ‘long unsigned int’} may change the sign of the result [-Wsign-conversion]
   11 |     do_something(static_cast<uint64_t>(input_val));
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Do note that 'unsigned long long' and 'uint64_t' ('long unsigned') are distinct
types, though they are practically identical on x86-64:
```
static_assert(sizeof(uint64_t) == sizeof(unsigned long long));
static_assert(std::numeric_limits<uint64_t>::min() ==
std::numeric_limits<unsigned long long>::min());
static_assert(std::numeric_limits<uint64_t>::max() ==
std::numeric_limits<unsigned long long>::max());
static_assert(!std::is_same<uint64_t, unsigned long long>::value);
```

I tested this in compiler explorer (https://godbolt.org/z/4xKdeq9EG) and it is
reproducible with trunk as well as GCC 10.1 to 14.2.
Though as Andrew Pinski mentioned, GCC 9 gives a different warning, making it
look like the static_cast was completely ignored:
<source>:11:18: warning: conversion to 'long long unsigned int' from 'short
int' may change the sign of the result [-Wsign-conversion]
   11 |     do_something(static_cast<uint64_t>(input_val));
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Reply via email to