sizeof in static const member initialization

c++ initialize const member in constructor
c ( static const member variable initialization)
c static const initialization in header
initialize static member c
in-class initialization of static data member of non literal type
c constexpr
c++11 static member initialization
const member variable c++

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, or enumerator" in VC++
};

I got compiler error in VC++ and no errors in IAR. Which compiler is right, what C++ standart says about it?

Your MSVS versions are quite old, so based on that, and assuming they default to C++03, they are correct to reject your code. I'll quote n1905, which for our purposes is pretty close to the C++03 standard.

9.4 [class.static] (emphasis mine)

If an unqualified-id (5.1) is used in the definition of a static member following the member’s declarator-id, and name lookup (3.4.1) finds that the unqualified-id refers to a static member, enumerator, or nested type of the member’s class (or of a base class of the member’s class), the unqualified-id is transformed into a qualified-id expression in which the nested-name-specifier names the class scope from which the member is referenced. The definition of a static member shall not use directly the names of the non-static members of its class or of a base class of its class (including as operands of the sizeof operator). The definition of a static member may only refer to these members to form pointer to members (5.3.1) or with the class member access syntax (5.2.5).

static const member initialization probl - C++ Forum, I am having a problem concerning a static const member variable I want The variable should denote the size of a member array which I don't  YES you can but only for int types. If you want your static member to be any other type, you’ll have to define it somewhere in a cpp file. class A{ private: static const int a = 4; // valid static const std::string t ; // can't be initialized here

StoryTeller's answer specifies why this didn't work on visual-studio-2005. Namely because it wasn't supported until c++11.

As far as visual-studio-2013 it's not fully c++11 compliant. But I've validated that this code works around the deficiency:

static const unsigned long b = sizeof(decltype(a))

If you want something that will work with visual-studio-2005 as well, consider making b a global, instead of a static member of A:

const unsigned long b = sizeof(A().a)

Non-static data members, Non-static data members are declared in a member specification of a class. 2}; // non-static data member with default member initializer (C++11) std::string s, struct S { int m; static const std::size_t sz = sizeof m; // OK: m in  2) Static or thread-local object of class type that is initialized by a constructor call, if the constructor is constexpr and all constructor arguments (including implicit conversions) are constant expressions, and if the initializers in the constructor's initializer list and the brace-or-equal initializers of the class members only contain constant expressions.

static const-qualified member in-class initialisers using non-static members were not part of the C++ standard until C++11.

The earliest MSVC compiler that fully supports C++11 is MSVC2017.

That compiler will compile your code correctly.

Constant initialization, Constant initialization is performed instead of zero initialization of the static and and the brace-or-equal initializers of the class members only contain constant  You still need to define the static member in an enclosing namespace. The following example demonstrates this: #include <iostream> using namespace std; struct X { static const int a = 76; }; const int X::a; int main() { cout << X::a << endl; } The tokens = 76 at the end of the declaration of static data member a is a constant initializer.

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 <stdio.h>

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;
}

C++ Tutorial: Static Variables and Static Class Members, A static variable can be initialized only with a constant expression. int x; // x set to 0 int y = 50; // 50 is literal constant int z = sizeof(int); // sizeof ok int zz = 10 * x;  Static member functions are not associated with any object. When called, they have no this pointer. Static member functions cannot be virtual, const, or volatile. The address of a static member function may be stored in a regular pointer to function, but not in a pointer to member function. Static data members. Static data members are not associated with any object.

The case for Auto Non-Static Data Member Initializers, First, a static data member initializer is always evaluated and s { static const int foo = 42; }; int s::foo = 42; s { static const auto foo = 42; }; you can not do within auto-nsdmi: calling sizeof referring to *this (even in decltype),  My ultimate goal is to store, as static const storage, a series of remote control codes (CODE), each of which will have a frequency, a mode, and two different collections of BURST_PAIR items. Each code will most likely have a different number of single and repeat BURST_PAIR items in them.

DCL56-CPP. Avoid cycles during initialization of static , Constant initialization (3.6.2) of a block-scope entity with static storage duration, Definitions of explicitly specialized class template static data members have the lazy-initialized cache. static int cache[17]; if (i < (sizeof(cache) / sizeof(int))) { if​  I am having a problem concerning a static const member variable I want to use to set a certain property of my class during development time. The question actually concerns proper implementation as I do have a solution that "works" at least.

Chapter 8: Static Data And Functions, C++ solves the problem by defining static members : data and functions, common Static const data members should be initialized like any other static data member: nPersons, sizeof(Person *), reinterpret_cast<int(*)(void const *, void const  This page was last modified on 10 April 2020, at 06:53. This page has been accessed 120,823 times. Privacy policy; About cppreference.com; Disclaimers

Comments
  • Which MSVC version are you using?
  • MSVS 2013 and MSVS 2005.
  • I'd imagine this means that you are working with an up to date version of IAR... versus VS2005... which is not up to date.
  • Keyword is should. And I'm not sure C++11 was the default standard for MSVC2013 back then.
  • According to this source, C++11 is not entirely supported even in MSVC2015.
  • @AlgirdasPreidžius You're not wrong... Even VS2015 has some outstanding C++11 deficiencies. Or maybe I should just say C++ standard deficiencies :( I'll reword just to be clear. What I was trying to communicate is that sizeof(a) is actually valid code now... It's just a Visual Studio discrepancy that prevented it from compiling.
  • @StoryTeller Yeah, I've clarified. As has been pointed out VS2013 didn't even claim to be C++11 compliant.
  • I believe this to be correct (though I don't have VS2015 to check.) I just couldn't figure out the feature name that Microsoft gave to this portion of the spec, so I couldn't find anything authoritative on the timeline in which support was gained. decltype can be used to workaround this deficiency circa VS 2012. So I'd really like to read about the limitation... If you could provide a link to source your statements it's worth a +1 to ya!
  • @JonathanMee: Informally, you could check the value of __cplusplus on the compiler: MSVC2017 is the earliest one that has this to a C++11 value. Probably only worth 1/2 in integer arithmetic ;-)
  • This answer does provide some circumstantial evidence of which behavior is correct. As such I feel bad about the fact someone downvoted here, especially when such effort was put into this answer. So have a +1.
  • I don't feel bad about downvoting. I'm feeling good somebody could read it and understands it, even if they downvote or upvote that. The standards are not the real world, but the compilers out there, are.