Inconsistent behavior of MSVC and GCC with sizeof

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 unused variables.

Visual C ++ 2015, however, does not 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() compiles in order.

Is this a bug in MSVC, or am I missing something basic here?

+7
c ++ visual-c ++ compiler-bug visual-c ++ - 2015
source share
1 answer

This is a bug in MSVC.

C ++ 11/14 allows the use of a non-static member of a class in an undefined context, see 5.1.1 [expr.prim.general] p. thirteen:

An identifier that denotes a non-static data element or non-stationary function of a class member can only be used:

...

(13.3) - if this id-expression denotes a non-static data element and appears in an unvalued operand.

[Example:

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

- end of example]

Edit: it looks like MSVC accepts B::M and does not accept A::B::M , which is completely inexplicable behavior. I do not see how it can be anything but an error.

clang ++ as g ++ in C ++ 11 and C ++ 14 mode accepts a program. clang ++ in C ++ 03 mode rejects all 4 references to M (C ++ 03 has nothing similar to page 13.3), while g ++ in C ++ 03 mode still accepts them (this is probably g ++ C ++ 03).

+5
source share

All Articles