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.
