是什么导致此代码触发隐式 int 缩小?

What causes this code to trigger implicit int narrowing?

以下代码在指定 -Wc++11-narrowing 时使 clang 失败

#include <stdint.h>

extern uint8_t numbers[];
extern int n;

uint8_t test(int num) {
    uint8_t a{n > 0 ? *numbers : 2};
    return a;
}

(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};

我阅读了标准和相关问题,但我无法理解为什么具有两个结果 uint8_t 或可以透明缩小 uint8_t(即常数 2)的三元运算会导致提升到 int 然后想要明确缩小。

有人可以解释为什么会这样吗?谢谢!

条件表达式的第二个操作数的类型为 uint8_t。第三个操作数,文字 2,类型为 int.

当条件表达式的第二个和第三个操作数属于不同的算术类型时,将执行通常的算术转换,以便将它们转换为共同的类型。 [expr.cond]/7.2

在这种情况下,通常的算术转换涉及两种类型的提升,即 uint8_tint[expr.arith.conv]/1.5

因为int可以表示uint8_t类型的所有值,所以uint8_t的提升结果是intint 不受积分促销的影响,仍然是 int[conv.prom]

条件表达式的结果类型为 int。从 intuint8_t 的转换正在缩小,因为 uint8_t 不能表示类型 int.

的所有值