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)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~