static int count;
int main()
{
static int count;
}
Is there any difference between static variables declared inside and outside any function?
(I mean the scope and visibility of the variable count)
Your first count is only accessible within the module (code in that file). Your second count is only accessible within main.
When you declare outside of method it will be available to all static method functions written after its declaration. While declaring static variable in method will be accessible by only that method.
There's also a difference in dynamic initialization of globals (see here). To summarize, if you had:
static int count = bar();
int main ()
{
static int count = foo ();
}
The call to 'foo' will take place when main is executed, but the standard (C++ '03) doesn't require a call to 'bar' at all!
Related
I've been reading a bit about static functions and static member functions. From my understanding if a function is declared static then this function is only visible to it's translation unit and nowhere else. A static member function instead is a function that can be called without instantiating any object of its class (so you can use it like it was in a name space).
To clarify with static function I mean something like
static int foo(int a, int b)
{
return a + b;
}
And with static member function I mean
struct MyClass
{
static int foo(int a, int b)
{
return a + b;
}
}
Is this the only difference? or is the visibility within the same translation unit still a common feature for the two of them?
As you can see on this page, static actually has 3 different meanings depending on where it's used.
If it's used inside a block scope, like inside a function, then it'll make a variable persist across function calls.
If a class method is declared as static, then it's not bound to a specific instance of the class.
If a namespace member is declared as static, then it has internal linkage only.
Can I declare a global variable inside a non-member function?
Or in other words, a static equivalent for a non-member function?
And I'd like the variable to not be const - e.g. modifiable...
You can declare a global variable inside a function:
void f() {
extern int i;
}
But you'll also need to define it in the surrounding namespace, if you want to use it.
Being global, the definition doesn't have to be the same translation unit, but is subject to the One Definition Rule.
If, as indicated in the comments, you actually want a persistent local variable, initialised the first time the function is called, then that's exactly how a local static variable behaves:
void f() {
static int i = whatever(); // initialised the first time
i = something_else(); // the new value is preserved for next time
}
Can I declare a global variable inside a non-member function?
You can provide a declaration for a namespace level global variable inside a function. But I have the feeling that you are looking for something else and did not get the wording quite right:
Or in other words, a static equivalent for a non-member function?
You can declare (and define) a local static variable in a function. The lifetime of which will extend beyond the execution of the function (i.e. the variable will be there for the next function execution and so on).
int nextValue() {
static int counter = 0;
return ++counter;
}
Note that this is not a global, as global implies accessibility from any context and this variable is only accessible within nextValue.
And I'd like the variable to not be const - e.g. modifiable...
This is completely orthogonal to where you declare/define a variable.
Test.h
class Test
{
public:
Test();
//some methods
private:
int var;
//some vars
}
Test.cpp
#include "Test.h"
int a;
void func()
{
//some code here
}
Test::Test()
{
//some code
}
Variable a and function func() are non-member and non-static.
What is the lifetime of variable a and function func()?
Consider Test class as a part of a shared library. Can other classes of that library access a or func() by resolution operator ?
What is difference between static declaration of variable a/ func() and nonstatic declaration of a/func() ?
Variables and functions have the same scope: they exist from their point of declaration onward.
This is relatively different from attributes and methods of a class whose scope is limited to the class itself and where order matters less (though it may... for types).
The MSDN page is the answer to your question. It defines scope and Lifetime.
a have scope and life time through out the file since its global.
func() doesnt have scope or lifetime. they only have visibility.
if its part of shared library also functions and global variables can be accessed by other parts provided library is visible.
In this case being static doesnt make much of a difference. But local variables when made static gets global scope but will have only local visibility.
Variable a is a global variable, its scope is entire program runtime i.e its created during your program startup and destroyed during program exit. func is a global function and functions do not have any concept of scope attached to them.
In C++ a scope, defined by C++11 §3.3.1/1, is a (possibly discontiguous) region of text where a name can be used unqualified to refer to the same entity.
A potential scope is the scope a name will have when there are no declarations of the same name within the potential scope.
The scope of your variable name and function name extends from the declaration, to the end of the file.
Variable "a" is a global variable to Test.cpp
and "func" is a normal function in Test.cpp.
Edit section:-
But u can use the same variable & method in different place if u do the same as listed below.
//file1.h
#ifndef FILE1_H
#define FILE1_H
extern int a;
extern void func();
#endif
//end of file1.h
//file1.cpp
#include"file1.h"
int a; // a=0 as it is global variable
static int x = 10;// Scope is limited, it can only be used in file1.cpp
static void func2(){
int z = x;
z = x+z;
//... some thing u r doing
}
void func(){
//... some thing u r doing
}
//end of file1.cpp
//file2.cpp
#include"file1.h"
//U can use variable "a" & method "func" defined in file1.cpp . For an eg:-
int add(int b){
func();//func defined in file1.cpp but used here
//func2(); //It will throw error if you remove the comment before func2 method as
//the scope of func2 is limited to file1.cpp as it is static method
return a+b;// a defined in file1.cpp but used here
}
int main(){
//some code exists here
return 0;
}
//end of file2.cpp
//================
There are lot of things by which u can play around. It just one of the example.
Like if you declare static global variable then scope of that variable is limited to that file only.
Variable "a" & "func" is accessible by other classes present in the same file where the Test Class is present.
If you declare any variable or method as static global variable then the scope of that variable & method is limited to that file as explained in above example.
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.
I know we cannot declare a static member variable inside a local class... but the reason for it is not clear.
So please can anybody explain it?
Also, why can't we access a non-static variable defined inside the function, within which the local class has been defined, directly in the local class member functions?
In the code given below:
int main(int argc, char *argv[])
{
static size_t staticValue = 0;
class Local
{
int d_argc; // non-static data members OK
public:
enum // enums OK
{
value = 5
};
Local(int argc) // constructors and member functions OK
: // in-class implementation required
d_argc(argc)
{
// global data: accessible
cout << "Local constructor\n";
// static function variables: accessible
staticValue += 5;
}
static void hello() // static member functions: OK
{
cout << "hello world\n";
}
};
Local::hello(); // call Local static member
Local loc(argc); // define object of a local class.
return 0;
}
Static variable staticValue is directly accessible while on the other hand the argc argument from main is not....
Static variables/functions of local class: try imagining the syntax, lifetime definition, and name-mangling implementation. I'd give up pretty quickly :)
No access to local variables from local class: because class instance might outlive the function scope. Example:
class interface; // base class declared somewhere
// creates specific implementations
interface* factory( int arg ) // arg is a local variable
{
struct impl0: interface { /* ... */ }; // local class
struct impl1: interface { /* ... */ }; // local class
// ...
switch ( arg )
{
case 0: return new impl0;
case 1: return new impl1;
// ...
}
return 0;
}
The locally declared class instance would now exist beyond the lifespan of the function local variables.
The two questions are related. I believe the answer is not clear to you because the static keyword in C++ has overloaded meanings.
When you define a static variable inside the function, you're really telling the compiler to initialize it only in the first call (so you can use the value across multiple calls). This is not exactly the same of the case of a file-scope or class-scope static variable.
With this in mind it might not make sense to define a static variable inside a local class, which is in turn defined inside a function.
Regarding your second question, a local class actually can access static variables defined in its enclosing function. The code below, for example, should compile in a standards-compliant compiler.
void f()
{
static int i;
class local
{
int g() { return i; }
};
local l;
/* ... */
}
int main()
{
f();
return 0;
}
Local classes don't have full access to their enviroment (thanks Richard)... you have to use e.g. references or pointers to work around that:
void f() {
int i = 0;
struct local {
int& i;
local(int& i) : i(i) {}
void f() { i = 1; }
};
local l(i);
l.f();
assert(i==1);
}
Another reason why you can't examine stack variables in the enclosing scope is that a function in the local class isn't necessarily called directly from the enclosing function.
In the example below, life would be easy if hello() were the only function in the class: To find the variable stackValue, hello() would simply need to look into its caller's stack frame. But here, I've introduced Local::goodbye(), which may or may not invoke Local::hello. In this case, how would Local::hello() know where to find the enclosing function's stack frame? (We'd need closures to make this work. I love closures, but I can't see that happening in C++.)
int main(int argc, char *argv[])
{
static size_t staticValue = 0;
int size_t stackValue = argc;
class Local
{
void hello()
{
cout << "stackValue is " << stackValue << "\n";
}
void goodbye()
{
if (stackValue == 42) {
hello();
}
else {
cout << "Goodbye!\n";
}
}
};
Local loc;
loc.hello();
stackValue = 42;
loc.goodbye();
return 0;
}
Static variables are initialized when program starts. Local classes are loaded when method is called. And unloaded when method call ends.
According to Wikipedia
In computer programming, a static
variable is a variable that has been
allocated statically — whose lifetime
extends across the entire run of the
program.
This is in contrast with loading and unloading of local classes having static variables declared
I think the reason that local classes can't have static members (or functions defined outside of the class) is more for syntactical than semantic reasons. Static members could be implemented just as in non-local classes: The static would have the lifetime starting at the first call to a function, just as static variables declared inside a function do. The compiler would have to make sure the static members were initialized when the first instance of the class was created.
Imagine the problem with name mangling now that the enclosing function signature becomes part of the name. ;-)
The reason you can't access local variables or parameters of a function in a local class is that it would complicate the code required to implement the class with little gain. The non-static members of a class are typically accessed via the "this" pointer or pointer to the specific instance. To access variables and parameters local to the enclosing function would require some mechanism to make them accessible. That mechanism might be fairly trivial if the functions were inlined, but what happens when they are not?