The following code makes clang to fail when -Wc 11-narrowing
is specified
#include <stdint.h>
extern uint8_t numbers[];
extern int n;
uint8_t test(int num) {
uint8_t a{n > 0 ? *numbers : 2};
return a;
}
(Same code in godbolt: https://godbolt.org/z/nTKqT7WGd)
8:15: error: non-constant-expression cannot be narrowed from type 'int' to 'uint8_t' (aka 'unsigned char') in initializer list [-Wc 11-narrowing]
uint8_t a{n > 0 ? *numbers : 2};
I read the standard and related issues but I cannot comprehend why a ternary operation with two results that are uint8_t
or can be transparently narroweduint8_t
(i.e: constant 2) result in a promotion to int
that then wants to be explicitly narrowed.
Can someone explain why this happens? Thanks!
CodePudding user response:
The second operand to the conditional expression has type uint8_t
. The third operand, the literal 2
, has type int
.
When the second and third operands to a conditional expression are of different arithmetic type, the usual arithmetic conversions are performed in order to bring them to their common type. [expr.cond]/7.2
In this case the usual arithmetic conversions involve the promotion of both types, namely uint8_t
and int
. [expr.arith.conv]/1.5
Because int
can represent all values of type uint8_t
, the result of the promotion of uint8_t
is int
. int
is unaffected by integral promotions and remains int
. [conv.prom]
The result of the conditional expression has type int
. A conversion from int
to uint8_t
is narrowing, since uint8_t
cannot represent all values of type int
.