sizeof in static const member initialization

前端 未结 4 1137
攒了一身酷
攒了一身酷 2021-01-23 14:00

I have such code:

class A
{
public:

    unsigned long a;
    static const unsigned long b = sizeof(a); // \"error C2327: \'A::a\' : is not a type name, static,          


        
4条回答
  •  北海茫月
    2021-01-23 14:48

    What do you have?

    You have the definition of a class named A.

    Your class has a unsigned long named a.

    Your class has a static const unsigned long named b.

    In certain C++ compilers, static and non-static members of a class can't be mixed, specially in the definition stage.

    What do you want?

    static const unsigned long b = sizeof(unsigned long);
    

    This is not exactly what you want, but this is how a smart compiler try to figure out.

    WHY???

    Because static members doesn't limit their scope to the object definition. They overpass the object scope and can be accessed from everywhere simply outputting A::b in the console using std::cout << A::b << std::endl, for example.

    Clang doesn't accept this construction, GCC does (both with -g -std=c++98)

    MSVC 19.14 (visual studio 15.7) doesn't accept it, too, but visual studio 15.8, with MSVC 19.15, does.

    Choose carefully.

    Where I check all this stuff?

    Here I check lots of compilers: https://godbolt.org/ This is one method, but you must evade this kind of hacks in the future.

    Magic code to check and blame

    The blame part is for mixing C and C++. It's only for compile with older versions without any checks:

    #include 
    
    class A
    {
    public:
    
        unsigned long a;
        static const unsigned long b = sizeof(a); // "error C2327: 'A::a' : is not a type name, static, or enumerator" in VC++
    };
    
    int main (void)
    {
        printf ( "Hello World" ); // I strongly not recommend using printf's in C++ code. 
        printf ( "%d", A::b );    // This is only to fill a functional example, not a rightful one.
        return 0;
    }
    

提交回复
热议问题