C++ 与为从未定义的静态成员对象创建链接符号不一致

C++ 与为从未定义的静态成员对象创建链接符号不一致,c++,linker,shared-libraries,language-lawyer,C++,Linker,Shared Libraries,Language Lawyer,这是一个相当经典的问题:“谁是对的,GCC还是clang,在哪里填写问题?” 最近,我遇到了一个代码,它使用了某种标记分派,可以归结为: struct X { enum { value = 1 }; }; struct A { static const X x; }; int useX() { return A::x.value; } 有两个核心问题:访问X::value的推荐模式是通过A::X.value(因为X是一些丑陋的模板类型),但从来没有定义静态X。这并不真正困扰

这是一个相当经典的问题:“谁是对的,GCC还是clang,在哪里填写问题?”

最近,我遇到了一个代码,它使用了某种标记分派,可以归结为:

struct X {
    enum { value = 1 };
};

struct A {
    static const X x;
};

int useX() { return A::x.value; }
有两个核心问题:访问
X::value
的推荐模式是通过
A::X.value
(因为
X
是一些丑陋的模板类型),但从来没有定义
静态X
。这并不真正困扰编译器,因为他们能够从
x
类型中猜测
.value
。但是
clang
在禁用优化的共享对象(
-O0
)的情况下创建缺少的符号条目

调用
clang++--shared so.cpp-o so.so-O0-fPIC&&nm-C-u so.so
在我的机器上使用以下命令生成结果:

w __cxa_finalize@@GLIBC_2.2.5
w __gmon_start__
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
U A::x
使用
g++
-O1
将摆脱
A::x

这里的
clang
是否需要定义
A::x
?这听起来像是基于一个观点

可以使用类成员访问来引用静态成员 语法,在这种情况下,将计算对象表达式

因此,
对象表达式
需要对对象求值

但是,即使clang符合标准,那么
-O0
-O1
之间也存在内部不一致,对吗


或者,这个主题是否超出了标准范围,只是实现定义的?

如果使用静态成员的唯一原因是避免键入
X
(名称较长),那么一个简单的解决方案应该是使用类型别名。@eerorika谢谢,我同意,但是我不是这个接口的所有者,代码本身是生成的。我问这个问题是为了了解为什么这个问题一开始就出现了。我已经通过使用
decltype(A::x)
在本地修复了它,并在作者的存储库中填充了一个问题。这闻起来像是ODR冲突,它是格式不正确的,NDR。我认为这允许不同优化级别之间存在“不一致性”。