MSVC 与 GCC 与 sizeof 的行为不一致
Inconsistent behavior of MSVC vs. GCC with 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 compiles it,只是警告未使用的变量。
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 = ...
和 main()
中的 s3 = ...
编译正常。
这是 MSVC 中的一个错误,还是我错过了一些基本的东西?
这是 MSVC 中的错误。
C++11/14 允许在非评估上下文中使用非静态 class 成员,请参阅第 5.1.1 [expr.prim.general] 页。 13:
An id-expression that denotes a non-static data member or non-static member function of a class can only be used:
...
(13.3) — if that id-expression denotes a non-static data member and it appears in an unevaluated operand.
[ Example:
struct S {
int m;
};
int i = sizeof(S::m); // OK
int j = sizeof(S::m + 42); // OK
— end example]
编辑:看起来 MSVC 接受 B::M
而不接受 A::B::M
,这是一个完全无法解释的行为。我不明白它怎么可能只是一个错误。
clang++ like g++ in C++11 and C++14 mode accepts the program。 C++03 模式下的 clang++ 拒绝对 M
的所有 4 个引用(C++03 没有任何类似 p.13.3 的内容),而 C++03 模式下的 g++ 仍然接受它们(这可能是一个 g++ C++03 模式错误)。
考虑以下代码:
#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 compiles it,只是警告未使用的变量。
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 = ...
和 main()
中的 s3 = ...
编译正常。
这是 MSVC 中的一个错误,还是我错过了一些基本的东西?
这是 MSVC 中的错误。
C++11/14 允许在非评估上下文中使用非静态 class 成员,请参阅第 5.1.1 [expr.prim.general] 页。 13:
An id-expression that denotes a non-static data member or non-static member function of a class can only be used:
...
(13.3) — if that id-expression denotes a non-static data member and it appears in an unevaluated operand.
[ Example:
struct S { int m; }; int i = sizeof(S::m); // OK int j = sizeof(S::m + 42); // OK
— end example]
编辑:看起来 MSVC 接受 B::M
而不接受 A::B::M
,这是一个完全无法解释的行为。我不明白它怎么可能只是一个错误。
clang++ like g++ in C++11 and C++14 mode accepts the program。 C++03 模式下的 clang++ 拒绝对 M
的所有 4 个引用(C++03 没有任何类似 p.13.3 的内容),而 C++03 模式下的 g++ 仍然接受它们(这可能是一个 g++ C++03 模式错误)。