Sim*_*mon 8 c++ language-lawyer
鉴于以下程序:
#include <cstdio>
#include <type_traits>
#include <utility>
struct EmptyClass {};
template <typename T, typename U>
struct Storage {
protected:
union Union {
T t;
U u;
} data;
char flag = false;
};
class AnotherEmptyClass {};
template <typename T, typename U>
class Derived : private Storage<T, U>, public AnotherEmptyClass {};
static_assert(std::is_standard_layout_v<Derived<char, EmptyClass>>);
int main() {
printf("Storage<char, EmptyClass>: %zu\n", sizeof(Storage<char, EmptyClass>));
printf("Derived<char, EmptyClass>: %zu\n", sizeof(Derived<char, EmptyClass>));
printf("Storage<char, char>: %zu\n", sizeof(Storage<char, char>));
printf("Derived<char, char>: %zu\n", sizeof(Derived<char, char>));
}
Run Code Online (Sandbox Code Playgroud)
这在 Linux 上输出 2 2 2 2,但在 Windows 上输出 2 3 2 2(使用 clang 和 MSVC)。
这是为什么?似乎使用EmptyClass作为联合的成员可以防止派生类上的空基类优化。但是对于标准布局类型,需要空基类优化。或者这种布局有不同的原因吗?
template <typename T, typename U>
class __declspec(empty_bases) Derived : private Storage<T, U>, public AnotherEmptyClass {};
Run Code Online (Sandbox Code Playgroud)
可以完成这项工作,但我不知道为什么 Microsoft 编译器默认禁用此行为,即使对于具有最新框架和主动一致性模式的 2019 版本也是如此。只是一个理论:这似乎是一个长期问题,也许大规模破坏功能代码的缺点被评估为不合理。
| 归档时间: |
|
| 查看次数: |
118 次 |
| 最近记录: |