Непоследовательное поведение MSVC против GCC с sizeof

Рассмотрим следующий код:

#include <cstddef>

class A
{
public:
struct B
{
int M;
};

static void StaticFunc();
};

void A::StaticFunc()
{
const std::size_t s0 = sizeof(::A::B::M);
const std::size_t s1 = sizeof(A::B::M);
const std::size_t s2 = sizeof(B::M);
}

int main()
{
const std::size_t s3 = sizeof(A::B::M);
return 0;
}

GCC компилирует это, просто предупреждение о неиспользованных переменных.

Однако Visual C ++ 2015 не может скомпилировать его:

error C2326: 'void A::StaticFunc(void)': function cannot access 'A::B::M'

на линии

const std::size_t s0 = sizeof(::A::B::M);
const std::size_t s1 = sizeof(A::B::M);

в StaticFunc(),

Другая линия s2 = ..., а также s3 = ... в main() компилировать нормально.

Это ошибка в MSVC, или я здесь что-то упускаю?

7

Решение

Это ошибка в MSVC.

C ++ 11/14 позволяет использовать нестатический член класса в не оцененном контексте, см. 5.1.1 [expr.prim.general] p. 13:

Выражение id, которое обозначает нестатический член данных или нестатическую функцию-член класса, может использоваться только:

(13.3) — если это id-выражение обозначает нестатический элемент данных и появляется в неоцененном операнде.

[ Пример:

    struct S {
int m;
};
int i = sizeof(S::m);        // OK
int j = sizeof(S::m + 42);   // OK

— конец примера]

Изменить: похоже, что MSVC принимает B::M и не принимает A::B::M, что является совершенно необъяснимым поведением. Я не понимаю, как это может быть что-то кроме ошибки.

clang ++, как g ++ в режиме C ++ 11 и C ++ 14, принимает программу. clang ++ в режиме C ++ 03 отклоняет все 4 ссылки на M (C ++ 03 не имеет ничего похожего на стр. 13.3), тогда как g ++ в режиме C ++ 03 по-прежнему принимает их (это, вероятно, ошибка режима g ++ C ++ 03).

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]