https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112463
Bug ID: 112463
Summary: ternary operator / -Wsign-compare inconsistency
Product: gcc
Version: 13.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: vincent-gcc at vinc17 dot net
Target Milestone: ---
-Wsign-compare is described in the man page as follows:
-Wsign-compare
Warn when a comparison between signed and unsigned values could
produce an incorrect result when the signed value is converted to
unsigned. In C++, this warning is also enabled by -Wall. In C,
it is also enabled by -Wextra.
But it can emit a warning even in the absence of comparisons between signed and
unsigned values. For instance, it can appear due to the 2nd and 3rd operands of
the ternary operator (these operands are not compared, just selected from the
value of the first operand). This affects the warning output by -Wextra.
Consider the following C code:
#include <stdio.h>
int main (void)
{
for (int c = -1; c <= 1; c++)
{
long long
i = c == 0 ? 0LL : (c >= 0 ? 1U : -1),
j = c >= 0 ? (c == 0 ? 0LL : 1U) : -1;
printf ("i = %lld\nj = %lld\n", i, j);
}
return 0;
}
(which shows that the ternary operator is not associative due to type
conversions). With -Wextra, I get:
ternary-op.c: In function ‘main’:
ternary-op.c:7:43: warning: operand of ‘?:’ changes signedness from ‘int’ to
‘unsigned int’ due to unsignedness of other operand [-Wsign-compare]
7 | i = c == 0 ? 0LL : (c >= 0 ? 1U : -1),
| ^~
But the "-Wsign-compare" is incorrect as there are no comparisons between
signed and unsigned values. Only -Wsign-conversion should trigger a warning.