c++ Update static int - c++

i am trying to update static int
test.h
static int Delay = 0;
void UpdateDelay();
test.cpp
#include "test.h"
void UpdateDelay(){
Delay = 500;
}
Main.cpp
#include "test.h"
int main(){
UpdateDelay();
std::cout << Delay << std::endl;
return 0;
}
output should be : 500
but it shows : 0
Thx

A global variable declared as static has internal linkage. This means that each translation unit (i.e. .cpp file) gets a private copy of that variable.
Changes done to a private copy of one translation unit won't have any effect on private copies of the same variable held by different translation units.
If you want to share one global variable, provide one definition for it in a single translation unit, and let all other translation unit refer it through a declaration that specifies the extern keyword:
test.h
extern int Delay;
void UpdateDelay();
test.cpp
#include "test.h"
void UpdateDelay(){
Delay = 500;
}
main.cpp
#include "test.h"
int Delay = 0; // Do not declare this as static, or you will give
// internal linkage to this variable. That means it
// won't be visible from other translation units.
int main(){
UpdateDelay();
std::cout << Delay << std::endl;
return 0;
}

If you put static int Delay in the .h file then each .cpp file will have it's own unique instance.
You want to use extern.
test.h
extern int Delay;
void UpdateDelay();
test.cpp
#include "test.h"
int Delay = 0;
void UpdateDelay()
{
Delay = 500;
}

you can't declare static int Delay in your .h what happens is per cpp is it makes their own version of "Delay"
what you want to do is in test.cpp declare static int Delay just above your UpdateDelay

In this usage, the keyword static means that each cpp file has its own independent copy of a variable called Delay. So the one which UpdateDelay() changes is not the one that main() prints.
If you want to use a single variable, make it extern instead: In the header file, put extern int Delay;. In one source file, put int Delay = 0;.

Related

can global variables be accessed and modified in various classes in C++

I have run into code spaghetti where i need to instrument flow control i.e., send data one at a time. How can i use global variable to solve this? If global variables don't work, what is the way to access and modify variables in multiples functions which could be in different classes
I tried the following (I am pasting partial code) but it gave me ld error that I could not resolve. I want to ask what might be the best and clean approach to solve this.
file1.h
int data_received; //global variable
class abc
{
.
.
.
public:
void send_data(..)
.
.
.
};
file1.c
void send_data()
{
while(!end_of_file)
{
read_line;
data_received = 0;
transmit_data(line);
while(data_received == 0)
cout<<"waiting for response before proceeding\n";
}
}
file2.c
//data receive class
void transmit_data()
{
....
....
....
//data sent upstream
data_received = 1;
}
I have searched many posts on stackoverflow but there is no clear answer. Some suggest to use extern variable but no clear example of external variable being modified in more than one class functions.
Please learn more about
Declare vs Define in C and C++.
compile vs link
define global variable
// file1.cpp
int data_received;
extern tell complier that data_received can be found when linker.
// file2.cpp
extern int data_received;
in addition, static can limit my_global_var only to be used in file defining it. example
// file3.cpp
static int my_global_var = 1;
Error will be occured in linker
// file4.cpp
extern int my_global_var;
You need to mark that extern in the header file and then define it once, either in file1.c or file2.c
For example
file1.h
extern int data_received;
file1.c
// initialize it
int data_received = 0;
file2.c
// either do this if the include is logically needed
#include "file1.h"
// or
extern int data_received;
// then use it normally
void foo() {
cout << data_received << endl;
}
Or if this is C++ you can declare that variable as a static variable in the class, define it in the .cpp file and then use it like a normal variable but prefixed with the scope resolution for the class. For example
class Something {
public:
static int data_received = 0;
};
void foo() {
cout << Something::data_received << endl;
}
By having your global variable deined in the header file, you will create a copy of it in any 'c' file which it includes. There far the ld will complain.
You need to declare it as 'extern' in the header file an then define it in a single 'c' file.
file1.h
extern int data_received;
file1.c
#include <file1.h>
int data_received = 0;
file2.c
#include <file1.h>
This way you would only define one copy of it and make it known to all files which include the header file.

Global stream in logging macro [duplicate]

I have a global int I want to change in different files, for some reason it doesn't work.
I have:
//test.h
#include <windows.h>
static int start1; //want to use this globally.
//declare
void something();
//test.cpp
#include "test.h"
extern int start1;
void something()
{
start1 = start1 + 1;
}
//main.cpp
#include "test.h"
#include "stdafx.h"
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
start1 = 3;
something();
return 0;
}
Why, when you go into something() is start1 0, instead of 3? I have been trying to make a global variable for hours, and it doesn't work. Please can someone clarify?
Don't declare a static variable in a header file. That will result in a separate variable existing for each translation unit (i.e. source file) that includes that header file.
The canonical pattern is to declare the variable as extern in the header file, and then define it "normally" in one source file.
You need to declare your int as extern in your header. It doesn't need any qualifiers when you define it in your .cpp file. The static qualifier actually means that the int you are declaring is only accessible in the current translation unit, so each .cpp file will get a different version of it.
If you put
static int start1;
in all source files, you'll get a static effect, in that the data will be separate addresses within each.
Then you can keep separate values/content for each unit.
BUT. This is NOT a global variable per se. A global variable is one that is shared between units, not the opposite. So there is a difference in static behaviour and global (extern) content... So the above answers are right, but I thought I might add a little perspective to the discussion.
I just ran a similar setup in C, and static variables act the same.

static variable cpp do not want to change

FileA.hpp:
static int a;
void change(int);
FileA.cpp
#include "FileA.hpp"
void change(int x) { a = x; }
main.cpp
#include "FileA.hpp"
#include <cstdlib>
#include <iostream>
int main()
{
a = 5;
std::cout<<a<<std::endl;
change(10);
std::cout<<a<<std::endl;
a = 20;
std::cout<<a<<std::endl;
system("Pause");
return 0;
}
My output is:
5
5
20
Can someone help me with this? Why variable 'a' don't want to change in function
which is in FileA.cpp.
How to fix this. When I make change(int x) inline in "FileA.hpp" it works fine.
The static keyword on a global variable gives that variable internal linkage. It means that any translation unit that has that definition will have its own copy of the object. So the a object that main.cpp sees and that FileA.cpp sees are different objects. change will modify one of them, but main will output the other.
If you were intending static to mean that the object has static storage duration, global variables (or variables at namespace scope in general) have static storage duration anyway. You don't need to mark them static. However, if you remove static, you'll have another problem; you'll have multiple definitions of a across translation units.
The correct way to do this is to declare a as extern in the FileA.hpp file:
extern int a;
Then in a single translation unit (probably in FileA.cpp, define the object:
int a;
This means that any object that includes FileA.hpp will have the declaration of a (which is fine) and only one translation unit will have the definition of a. Perfect.
You declare a in the header file, which when included creates two copies of it, one in main.cpp and one in FileA.cpp. When you do a = 5; you assign to the copy from main.cpp, while when calling the function change, it changes the copy in FileA.cpp.

Not able to understand static behaviour

I wrote in
// In file t.h
#ifndef __t_h__
#define __t_h__
static int abc;
#endif
--
//In main.c
#include <stdio.h>
#include "t.h"
int main()
{
abc++;printf("%d \n", abc);
test();
}
- -
//In test.c
#include <stdio.h>
#include "t.h"
void test()
{
abc++;
printf("%d \n", abc);
}
When I run the project I found the output of abc is 1 and 1.
But when I change it to int abc in t.h. The output of abc = 1 and 2.
Why static is not retaining the value when the control reaches to test.c file.
If it won't retain then why should not it provide an error as the static variable can not be shared between/among the files?
static variables has internal linkage which means each translation unit gets its own copy.
So in your program each .cpp file which includes t.h has its own copy of the static variable, which in turn means, there are two objects in the memory. You can try printing their addresses to confirm this, as they will be different.
That makes the situation pretty simple: if you change the object in one .cpp, it doesn't reflect in the other .cpp file, because the object in the other .cpp file is a different object. Why should it change?
But when you change it to int abc (i.e don't make it static), then each translation unit has same object. If you change it in one file, it will be reflected in other file also, as expected.
As for sharing, then yes, static objects can be shared between two functions in the same translation unit, but they cannot be shared between two translation units.
Search for translation unit on this site, you will get many topics on it. Read them, then you will understand it fully.
When the preprocessor is done with your code, main.c looks like
// omitted stuff from stdio
static int abc;
int main()
{
abc++;printf("%d \n", abc);
test();
}
and test.c looks like
// omitted stuff from stdio
static int abc;
void test()
{
abc++;
printf("%d \n", abc);
}
So each file contains its own variable abc that is not accessible from the other.
One solution would be to change t.h to
#ifndef __t_h__
#define __t_h__
extern int abc;
#endif
and then change main.c to
#include <stdio.h>
#include "t.h"
int abc;
int main()
{
abc++;printf("%d \n", abc);
test();
}
You can think about it like this: there's now only one int abc in your program, in main.c but test.c knows about its existence because the extern int abc tells test.c that somewhere else in the project there is an integer called abc that it will be able to find at link time.
When you declare a static variable in header file a copy of the static variable is created in each Translation unit where the header is included. So each of the translation units involved in your program has its own copy of abc now and hence you get the observed behavior.The behavior is not what you expected but it well defined one.
static variable can not be shared between/among the files?
No they cannot be! that is the very purpose of making them static
static variables have internal linkage. Their scope is restricted to the the translation unit in which they are declared. They cannot be accessed beyond the TU.If you want to share the same variable across different Translation units You should drop the static and use extern, which gives the variable an external linkage and hence visibility across different translation units.
Good Read:
How do I use extern to share variables between source files?
In C, static has two usages:
1, Use static keyword to limit the var's scope in the translation unit. To make this simple, if you have two files: a.c, b.c and you wrote:
static int varA;
in a.c, then this means varA could only be used in a.c, if you want to use varA in b.c, you should remove the static keyword, and add extern int varA; in b.c, what people usually do is we create another file called: a.h, and write extern int varA; in a.h, and we simply include "a.h" in b.c, so we could write every variable we want to extern in a.h and use a single include "a.h" to make these variables or functions legal in other .c files(i.e. source files)
2, Using static to define a local variable in a function, for instance:
int TheFunction()
{
static int var = 0;
return ++var;
}
Because you used the static keyword on a local variable var, this variable will not loss when TheFunction() is returned.
The first time you call TheFunction() you will get 1, the second time you call TheFunction() you will get 2, and so on.
Next, lets see the usage of static in C++.
Because any C++ complier can complie a C code, so the 2 usages above is also in C++.
another two usages is:
1, static member variable.
2, static member function.
Lets see the code directly:
#include <iostream>
using namespace std;
class Test
{
public:
Test() : m_nNormalVar(0)
{
}
public:
// You need to init this static var outside the class
// using the scope operator:
// int Test::m_nStaticVar = 0;
static int m_nStaticVar;
// You can init this const static var in the class.
const static int m_nConstStaticVar = 10;
// This is just a normal member var
int m_nNormalVar;
};
int Test::m_nStaticVar = 0;
int main(int argc, char *argv[])
{
Test a;
Test b;
a.m_nStaticVar++;
a.m_nNormalVar++;
cout << b.m_nStaticVar << endl;
cout << b.m_nNormalVar << endl;
return 0;
}
a and b are objects of class Test they have the same m_nStaticVar and the same m_nConstStaticVar, but they have their own m_nNormalVar this is a static member variable.
#include <iostream>
using namespace std;
class Utility
{
public:
// This is a static member function, you don't
// need to have a concrete object of this class
// to call this function.
static int SelectMax(int a, int b)
{
return a > b ? a : b;
}
};
int main(int argc, char *argv[])
{
// No objects of class Utility
cout << Utility::SelectMax(2, 1) << endl;
return 0;
}
So this is a static member function of a class in C++.
These four ways of static's usage is all I known, if there are still some other usages, please help to edit this post, thx:)
EDIT:
Add static global function
1, Use static keyword to limit the function's scope in the translation unit. To make this simple, if you have two files: a.c, b.c and you wrote:
static void StaticFunction();
in a.c, so you can only call StaticFunction() in a.c, if you want to call this function in b.c you should remove the static keyword and then delcare it before the usage. Or just declare it in a.h and include "a.h" in b.c

global variable doesn't work

I have a global int I want to change in different files, for some reason it doesn't work.
I have:
//test.h
#include <windows.h>
static int start1; //want to use this globally.
//declare
void something();
//test.cpp
#include "test.h"
extern int start1;
void something()
{
start1 = start1 + 1;
}
//main.cpp
#include "test.h"
#include "stdafx.h"
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
start1 = 3;
something();
return 0;
}
Why, when you go into something() is start1 0, instead of 3? I have been trying to make a global variable for hours, and it doesn't work. Please can someone clarify?
Don't declare a static variable in a header file. That will result in a separate variable existing for each translation unit (i.e. source file) that includes that header file.
The canonical pattern is to declare the variable as extern in the header file, and then define it "normally" in one source file.
You need to declare your int as extern in your header. It doesn't need any qualifiers when you define it in your .cpp file. The static qualifier actually means that the int you are declaring is only accessible in the current translation unit, so each .cpp file will get a different version of it.
If you put
static int start1;
in all source files, you'll get a static effect, in that the data will be separate addresses within each.
Then you can keep separate values/content for each unit.
BUT. This is NOT a global variable per se. A global variable is one that is shared between units, not the opposite. So there is a difference in static behaviour and global (extern) content... So the above answers are right, but I thought I might add a little perspective to the discussion.
I just ran a similar setup in C, and static variables act the same.