Consider the following code:
#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, just warning about the unused variables.
Visual C++ 2015 however fails to compile it with:
error C2326: 'void A::StaticFunc(void)': function cannot access 'A::B::M'
on the lines
const std::size_t s0 = sizeof(::A::B::M);
const std::size_t s1 = sizeof(A::B::M);
in StaticFunc()
.
The other line s2 = ...
, and s3 = ...
in main()
compile fine.
Is this a bug in MSVC, or do I miss something basic here?
It is a bug in MSVC.
C++11/14 allows a non-static class member to be used in a non-evaluated context, see 5.1.1 [expr.prim.general] p. 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]
Edit: it looks like MSVC accepts B::M
and doesn't accept A::B::M
, which is a completely inexplicable behaviour. I don't see how it could be anything but a bug.
clang++ like g++ in C++11 and C++14 mode accepts the program. clang++ in C++03 mode rejects all 4 references to M
(C++03 doesn't have anything like p. 13.3), whereas g++ in C++03 mode still accepts them (this is probably a g++ C++03 mode bug).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With