Bug 115626 - relax -Wsign-conversion when initializing from a literal
Summary: relax -Wsign-conversion when initializing from a literal
Status: RESOLVED DUPLICATE of bug 92675
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 15.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2024-06-25 03:13 UTC by Michael Kenzel
Modified: 2024-06-25 15:43 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Kenzel 2024-06-25 03:13:47 UTC
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?
Comment 1 Andrew Pinski 2024-06-25 03:18:14 UTC
-1ul and ~0ul are portable by the way.
Comment 2 Andrew Pinski 2024-06-25 03:18:52 UTC
>may not work reliably for types for which no literal suffixes exist (e.g.: extended integer types)

You can always do `~(cast)0` too.
Comment 3 Andrew Pinski 2024-06-25 03:20:41 UTC
(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.
Comment 4 Andrew Pinski 2024-06-25 03:24:45 UTC
dup.

*** This bug has been marked as a duplicate of bug 92675 ***