Inconsistent behavior of MSVC vs. GCC with sizeof
Asked Answered
T

1

7

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?

Takeover answered 3/10, 2016 at 13:8 Comment(6)
I see no reason why it shouldn't work. So I would say with some degree of confidence it's a VS bug.Barm
since these compiler vs compiler questions are popular here, let's open the pools:Barm
A) it's a VS bugBarm
B) it's a gcc bugBarm
C) I don't want to vote, just show me the resultsBarm
@Barm We have a winner.Clovah
C
5

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).

Claytonclaytonia answered 3/10, 2016 at 13:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.