为什么 C++20 允许此值向下转换(static_cast 为对象类型)?

Why is this value downcast (static_cast to object type) allowed in C++20?

令我惊讶的是,gcc 11.2 accepts this code,但仅限于 C++20 模式:

struct Base {};
struct Derived : Base { int i; };
int f(Base& b) { return static_cast<Derived>(b).i; }
//                                  ^~~~~~~ oops, forgot the `&`

同样,MSVC 19.29 在 C++20 模式下接受它,在 C++17 模式下拒绝它,但 clang 即使在 C++20 模式下也拒绝它。

查看汇编程序输出,f 总是 returns 0,因此它忽略了传递给 f 的任何潜在 Derived 的实际数据。

这是 UB,还是在 C++20 中合法,如果是,为什么?

在 C++20 中是合法的。

[expr.static.cast]/4:

An expression E can be explicitly converted to a type T [...] if T is an aggregate type ([dcl.init.aggr]) having a first element x and there is an implicit conversion sequence from E to the type of x.

[dcl.init.aggr]/2:

The elements of an aggregate are: [...] for a class, the direct base classes in declaration order, followed by the direct non-static data members ([class.mem]) that are not members of an anonymous union, in declaration order.

因此 Derived 是第一个元素为 Base 的聚合,并且自 C++20 起,允许从其第一个元素创建聚合。

此功能在P1975R0“修复括号聚合初始化的措辞”中引入。