You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何[[no_unique_address]]在MSVC中会与基类产生冲突?

问题:[[no_unique_address]]在MSVC中与基类冲突导致结构体大小不符合预期?

以下程序在除MSVC外的所有编译器中返回1,而在MSVC中返回2:

struct E1 { };
struct E2 { };
struct
#ifdef _MSC_VER
    __declspec(empty_bases)  // This doesn't make any difference
#endif
    S : E1
{
    char c;
    [[no_unique_address]]
#ifdef _MSC_VER
    [[msvc::no_unique_address]]
#endif
    E2 e;
};

int main() { return sizeof(S); }

为何[[no_unique_address]]特性在MSVC中会与基类产生冲突,导致结构体S的大小不符合预期?按特性设计,它不应让成员e与c重叠吗?


回答

这是因为MSVC在处理空基类和带[[no_unique_address]]的空成员时,没有正确适配空基类优化(EBO)与空成员优化的组合规则。

按照C++标准,[[no_unique_address]]允许空类型的成员与其他非静态数据成员、基类子对象共享内存地址,只要它们的类型互不相同即可——这里E1和E2是不同的空类型,c是char类型,理论上E2成员e完全可以和c或基类E1的子对象重叠,让S的大小保持为1。

但MSVC的实现存在限制:当结构体同时包含非空数据成员(比如这里的char c)和空基类时,它不会将带[[no_unique_address]]的空成员与非空成员进行地址重叠。反而会为空成员e单独分配一个字节,最终导致sizeof(S)变成2。

你添加的__declspec(empty_bases)和[[msvc::no_unique_address]]没有效果,因为MSVC本身支持空基类优化,也能识别标准的[[no_unique_address]]特性,只是在这种“空基类+非空成员+带no_unique_address的空成员”的组合场景下,处理逻辑存在问题,和这些额外修饰无关。


内容的提问来源于stack exchange,提问作者user541686

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 06:35:00