Initialization of static class variable inside the main - c++

I have a static variable in the class.
I am Initializing that in the global scope, its works fine.
But
When I try to Initialize in the main linker throws an error.
Why it so.
class Myclass{
static int iCount;
} ;
int main(){
int Myclass::iCount=1;
}
And In global scope why I have to specify the variable type
like
int Myclass::iCount=1;
As In my class I am definig iCount as integer type why not.
Myclass::iCount =1 ; in //Global scope

The section $9.4.2/7 from the C++ Standard says,
Static data members are initialized
and destroyed exactly like non-local
objects (3.6.2, 3.6.3).
Note the phrases "initialized" and "exactly like non-local objects". Hope that explains why you cannot do that.
In fact, static members are more like global objects accessed through Myclass::iCount. So, you've to initialize them at global scope (the same scope at which class is defined), like this:
class Myclass{
static int iCount;
} ;
int Myclass::iCount=1;
int main(){
/*** use Myclass::iCount here ****/
}
Similar topic:
How do static member variables affect object size?

Because C++ syntax doesn't allow this. You need to instantiate your static variable outside of the scope of some function.
Besides you forget a semicolon ; after your class ending bracket.

this is the correct C++. Outside of a function, in a cpp file. the initialisation is done at the beginning/launching of the executable. ( even before calling main() );
//main.h
class Myclass{
static int iCount;
}; // and don't forget this ";" after a class declaration
//main.cpp
int Myclass::iCount=1;
int main(){
}

From C++ standard (§8.5/10):
An initializer for a static member is in the scope of the member’s class.
class Myclass has global scope and you tried to initialize its static member in the narrower scope - of the function main.

The static initialisation occurs before main is called by the run-time initialisation.
Placing it within a function is not allowed because that is where locally scoped objects are declared. It would be confusing and ambiguous to allow that.

Related

Why static global variables initialized to zero, but static member variable in class not initialized?

static int counter // will initalized to 0
but if I make that variable inside a class, it's not initialized and I have to initialize it outside of class
class Test {
static int counter; // not initialized
};
...
Test::counter = 0;
I know the static variables are stored in BSS segment in memory and initialized by default to 0, so why is it when I make a static in class not initialized?
Why static global variables initialized to zero, but static member variable in class not initialized?
Because the declaration for a non-inline static data member inside the class is not a definition.
This can be seen from static data member documentation:
The static keyword is only used with the declaration of a static member, inside the class definition, but not with the definition of that static member. The declaration inside the class body is not a definition and may declare the member to be of incomplete type (other than void), including the type in which the member is declared:
Also the out of class definition Test::counter = 0; is incorrect. It should instead be int Test::counter = 0;
The question is based on a false premise. Static member variables are subject to zero initialization. The following code would perform the expected zero initialization of counter.
class Test {
static int counter; // declaration, not defined yet
};
int Test::counter; // definition with zero-initialization
It's not the initialization that is required, but the definition. Without the definition, the compiler has no place in which to perform the initialization, zero or otherwise.
See also Undefined reference to a static member and Defining static members in C++ for more background information.

c++: Static variable defined in constructor

I'm curious about what is really happening "under the hood" here. I'm creating a Class with an ID variable automatically assigned when the constructor is called, depending on how many instances have been created in the past.
Class:
class MyClass{
int ID;
public:
MyClass(){
static int id{1}; // Seems to be redefined every time the constructor is called.
ID = id++;
}
};
Main:
int main()
{
MyClass a; // ID = 1
MyClass b; // ID = 2
MyClass c; // ID = 3
return 0;
}
I'm only used to use static member variables that are initialized in the global scope (i.e. MyClass::staticVariable = 1), so this "in-class" initialization confuses me, as what is really happening.
Is the static variable defined only the first time the line is run, and then ignored? Is this the general behaviour for any function AND member function?
For all intents and purposes the behavior is the same as static member variables that are initialized at global scope, which you seem to grasp. The only difference I can see between the two is the scope, the static variable declared in the constructor is only avalilable at constructor scope, whereas a static variable declared as class member is, of course, avalilable at class scope, following the access rules, as all the ohters.
id is a static local variable. Using the static keyword on a local
variable changes its duration from automatic duration to static
duration.
According to cpp ref, the initialization is done the first time control passes through their declaration. On all further calls, the declaration is skipped.
Static local variables and lifetime-of-a-static-variable are some interesting detailed articles.

Initialization of a static member inside a global function

My code looks like this:
class myClass{
public:
static int a;
};
void myFunc()
{
int myClass::a = 1;
}
I see the following compilation error
error C2655: 'myClass::a' : definition or redeclaration illegal in current scope
I make the following change and everything goes fine. Any idea?
class myClass{
public:
static int a;
};
int myClass::a = 1;
void myFunc()
{
}
Logically think like this:
If you never call myFunc(), myClass::a is not defined. So it must be in global scope.
In your first code snippet, potentially you may use myClass::a even without defining it, so it not allowed and former syntax is not valid C++.
Static variable must be initialized before program start, so if you initialized it in a function, there is chance that it will not be initialized at all. So the compiler should pose this as an error. Static variable is allocated at compile time (before program run). Hope this help.
If you define the static member data in a function, it's linkage is internal to the function. The linkage required for them is global.

Static member in class

I have a question about static and static const variable in class.
Especially curious about the memory status about static and static const.
In the following code,
#include <iostream>
using namespace std;
class test{
public:
static const int testConstStatic =1;
static int testStatic;
};
int test::testStatic = 0;
int main(){
cout << test::testStatic << endl;
cout << test::testConstStatic << endl;
return 0;
}
why does 'static int testStatic' need definition to be used and if not, I got 'undefined reference' about testStatic?
Does this definition make linkage about testStatic?
And what about testConstStatic?
Thanks in advance!
UPDATED!!
The main reason of this question was that when I declared static variable as global which surely not defined and printout then no message about 'undefined reference' BUT for the static variable in CLASS without definitino it show the message 'undefined reference'
#include <iostream>
using namespace std;
static int testStaticInGlobal;
class test{
public:
static int testStatic;
};
int test::testStatic = 0;
int main(){
cout << test::testStatic << endl; // 'Undefined reference' error without definition
cout << testStaticInGlobal << endl; // no error without definition
return 0;
}
Thanks!
All variables in C++ must be defined before use. How this definition occurs is dependent on the type of variable.
For non-static class member variables, the definition may be implicitly performed by the class's constructor (which may itself be implicit).
Since static variables, by definition, are not intialized by a constructor, static member variables must always have an explicit definition.
For convenience, C++ allows the definition of a static const member to be combined with its declaration, as you have done, under certain circumstances. Conceptually, the static const int testConstStatic = 1; is doing two distinct things: declaring the testConstStatic member, and defining it to have a value of 1. For whatever reason, the language designers did not choose to allow these two steps to be combined for non-const static members.
Incidentally (to address Ed Heal's comment), a non-static const member (like any non-static member variable) must be defined at construction of object; it will not change after construction is completed, but it may have a different value for each instance of the class, unlike a static const member, which will always have one and only one value for the entire duration of the program.
static const int members are a special case. They're treated as compile-time constants in most usage, and thus a storage location for them isn't required. The only exception is when you try to make a pointer or reference to this variable, then it needs a place to live and you'll need to provide a definition.
static member variable needs to be defined outside the class. That's a rule.
C++11 onwards, const static members usually don't have to be defined outside the class.
Static data members are treated as global variables shared among the object instances, so they ned to be defined once only, and safe bet is outside the class.
const variables are by definition static. So the static in static const is redundant. i.e. just const will do.
The static is required for the static int because without it, the variable is a normal non-static member variable that is only defined for the instance.

Private static declaration and subsequent initialization

A .cpp file has a bunch of class definitions . One class has a private static member as follows:
class SomeClass:public SomeParentClass
{
private:
static int count;
};
and right after the class is defined, the count attribute to initialized to zero as follows:
int SomeClass::count = 0;
Coming from the Java/C# world I am having trouble understanding at which point is count initialized to zero? Is it when the SomeClass is instantiated? Also, the class definition has the count type to be int, why does the SomeClass::count has to have an int in front of it?
And my last question is, since the count attribute is private shouldn't its visibility be restricted when it is initialized outside the class definition?
Thanks
Static members of the class are initialized in arbitrary order upon your program's start-up
The static int count; in the class is a declaration of your static variable, while int SomeClass::count = 0; is its definition. All definitions in C++ require to specify a type.
The fact that the definition of the count appears to have occurred in the file scope, the actual scope of the SomeClass::count remains private, as declared.
Is it when the SomeClass is instantiated?
No, you can access it via SomeClass::count (assuming the function has rights to SomeClass's private members) before any instantiations. It's fully usable before you start making objects.
Why does the SomeClass::count has to have an int in front of it?
Well, because it's an int. Think of when you make function prototypes and definitions:
int func (int);
int func (int i) {return 1;} //you still need the int and (int i) here
func {return 1;} //NOT VALID - this is what count would be without int
Since the count attribute is private shouldn't its visibility be
restricted when it is initialized outside the class definition?
Static variable definition is an exception to access specifiers when defined in the normal manner, according to this answer.
The class static variable will behave as if it is initialized to 0 when the program starts. It is independent of class instantiation.
The C++ language requires a type before an identifier in a declaration.
The C++ syntax to initialize a class static variable makes it look like a global, but access to the variable is enforced during compilation.