Initializing an unsigned integer like unsigned int mask = -1; or unsigned int mask = ~0; is common practice, guaranteed to produce the desired value, and arguably the idiomatic way to initialize a bitmask to all bits set. Alternatives like explicitly providing the unsigned value unsigned long mask = 0xFFFFFFFFFFFFFFFFUL; are error prone, not generic, not portable as they cannot account for the varying width of types across target platforms, and may not work reliably for types for which no literal suffixes exist (e.g.: extended integer types). Mixing signed and unsigned arithmetic is a prolific source of bugs. Thus, enabling -Wsign-conversion is generally a good idea. However, doing so can lead to copious amounts of false positives in code that is heavy on the use of bitmasks. Quieting these warnings by means of explicit casts reduces readability. The likelihood that an unsigned integer being initialized from a literal -1 or ~0 constitutes a bug is small, while legitimate and perfectly safe uses of such constructs are ubiquitous. I would like to propose relaxing -Wsign-conversion to not warn upon initialization of an unsigned integer from a literal -1 or ~0 expression, or any unary - or ~ expression with literal operands and a signed value that does not exceed the range of the corresponding signed type, i.e., has a corresponding unsigned value with the same untruncated bit pattern. Maybe even consider allowing any constant expression with such a value. If changing the behavior of -Wsign-conversion is deemed not an option, maybe introducing something like a -Wnonliteral-sign-conversion or -Wnonconstant-sign-conversion option to explicitly opt into the warning only for cases that cannot be classified as most-likely harmless at compile time would be?
-1ul and ~0ul are portable by the way.
>may not work reliably for types for which no literal suffixes exist (e.g.: extended integer types) You can always do `~(cast)0` too.
(In reply to Andrew Pinski from comment #2) > You can always do `~(cast)0` too. That is: __uint128_t t = ~(__uint128_t)0; does not warn.
dup. *** This bug has been marked as a duplicate of bug 92675 ***