Это довольно классический вопрос «кто прав, 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
- это некрасиво шаблонный тип), но static X x
никогда не определяется. Это на самом деле не беспокоит компиляторы, так как они могут угадать .value
из x
типа. Но 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
? Это звучит так, исходя из пункта 11.3.8.1 .
Статический член может быть передан с использованием доступа члена класса.
синтаксис, в этом случае выражение объекта оценивается
Таким образом, object expression
требует оценки объекта.
Но, даже если clang соответствует стандарту, существует внутреннее несоответствие между -O0
и -O1
, верно?
Или, может быть, эта тема выходит за рамки Standard и просто определяется реализацией?