changing global variables - c++

I am facing a problem with global variables in c++. i have a function named iDraw(). and I planned to write two segments of code here which will be controlled by a global variable named flag. in the main function if i set flag to 1 and then call iDraw, then one portion of code will be executed; and if i set flag to 2 and then call it, then the other portion of code will be executed. but it isn't working expectantly.seems like when i am changing the value of flag in main function, it isn't working. It still holds the value which i declare in the top of program initially. what's the solution of overcoming it?
i used a header file named global.h where i declared all the global vars.
extern int flag=0, animflag=1;
/*
function iDraw() is called again and again by the system.
*/
void iDraw()
{
//place your drawing codes here
if(flag==1){
iClear();
iSetcolor(0,0,128);
iShowBMP(0,0, "Images\\intro.bmp");
}
if(flag==2){
//other codes here
}
}
int main()
{
iInitialize(900, 500, "demooo");
animflag=0;
flag=1; // seems like this line has no impact
iDraw();
return 0;
}

i used a header file named global.h where i declared all the global vars.
If your program contains more then one .cpp file which includes this global.h there is the problem. Because each of this .cpp files have its own copies of the flag variable and changing one of them will not change another copies.
You must define global variables in one of the .cpp file. In global.h you may provide extern declarations.
//*.cpp
int flag = 0;
//global.h
extern int flag;

Related

Correct way of initializing a class globally in C++

I know global is bad but just as a practice, is this the correct way to initialize a global class used between multiple object files?
Header 1.h
class test {
int id;
public:
test(int in){
id = in;
}
int getId(){
return id;
}
};
extern test t;
File 1.cc:
#include <iostream>
#include "1.h"
int main(){
std::cout << t.getId() << std::endl;
return 0;
}
File 2.cc:
#include "1.h"
test t(5);
Now what if instead of extern I use the static approach globally static test t(0); in the header?
Correct me if I'm wrong but that would compile fine however I would have 2 different unrelated copies of the same t in both object files and the final binary? Is that bad? Or does the linker sort it out to eliminate multiple copies?
There are global instances, not global classes.
What you have is a global instance. And yes, this sounds about right, until you get to multiple global instances which depend upon each other. Then the real fun will start.
Defining a variable as 'static' at global level means the variable will be defined in the compilation unit only (i.e. the '.o' file) and the symbol won't be exported by the compiler.
In other words: yes, there will be multiple variables with the same name but only visible to functions on the same compilation unit.
Besides, 'invisible' doesn't mean 'inaccessible'. You still can provide access to the variable. For example:
1.h
struct Test { int value; }; // Class definition
Test& get_t(); // Function declaration
1.cc
#include "1.h"
static Test t; // Variable declared as 'static'
Test& get_t() { return t; };
2.cc
#include "1.h"
#include <iostream>
int main()
{
std::cout << get_t().value << std::endl; // Static variable accessed
}
I use the static approach globally static test t;?
But your test class needs an int in parameter for the constructor, so you want:
static test t(0); // or whatever int you want
If you turn the extern to static in the header, you would define a static variable in each compilation unit in which the header is imported. So classes in different cpp files would no longer "communicate" via t, since each would have theirs. This is very error prone.
In addition, adding the definition of a static in a header is an extremely bad practice. When someone includes a header, one does not expect that it will create variables.
Including the declaration of t as extern is an acceptable practice. But be aware that if the header has a general purpose, this might reduce its reusability other projects.
More information of interest for you:
Must read: C++ Core Guidelines about source files
Must read: Guidelines for writing headers
StackOverflow: When are global variables recommended
Why global variables should be avoided if possible and when are they ok
If you put a variable declaration outside of any function, you're declaring the variable as 'global'. Ex:
1.cc
int this_is_global;
From here on you can use the variable in any function of '1.cc'.
For using the same variable in any other file, the compiler will need to know about it:
2.cc
extern int this_is_global;
Here, the keyword extern tells the compiler that the variable is declare somewhere else, letting the task of finding it to the linker.
If you miss to add the extern keyword here, the compiler will treat it as a new variable, and the linker will have two variables with the same name and will emit an error. All of your source files of your project except the first one will need the extern keyword to avoid duplicate symbols.
So common practice is to add the 'extern' declaration in an include file:
1.cc
int this_is_global;
1.h
extern int this_is_global;
2.cc
#include "1.h"
On the other side, the static keyword tells the compiler not to export the symbol. In other words: the variable will exists only in the source file it is declared. You could declare it once per source file and there will be different variables with the same name. Ex:
1.h
static int my_var;
1.cc
#include "1.h"
2.cc
#include "1.h"
This way, you'll end having two variables 'my_var' and changes to any of them won't affect the other.

How C++ differentiates between a call to global variable and declaration of a global variable?

This is the most confusing part for me from section Global Variables and linkage properties.
extern int g_var1;
Statement could be something like this when defining an external non-const global variable. I think I will write exactly the same for using that variable (through forward-declaration) in some other file. If both the statements are same, how C++ knows whether the variable was declared or was defined in a file?
If I understand your question correctly, you shouldn't write exactly the same in another file (namely, you shouldn't write "extern int g_var1" in two files). A good practice is to declare some variable global in a header file; make the definition in a cpp file that includes this header file. After doing this, you can use this variable in all of the files that will include the header file.
To illustrate, an example would be something like this:
variables.hpp
#pragma once
extern int g_var1;
variables.cpp
#include "variables.h"
int g_var1 = 1;
main.cpp
#include "variables.h"
#include <iostream>
using namespace std;
int main(){
cout << g_var1 << endl;
}
A statement of the form
extern int g_var1; // this is a declaration
is a declaration of a variable. The keyword extern makes sure of this.
If you write
int g_var1; // declare and define variable
you define it as well. You can declare a variable as many times as you like, but define it only once. You could therefore write
extern int g_var1;
in those files where you need to use the variable. Then during linking the compiler will resolve the definition of the variable (provided that you give the definition in some file of course).
When you say extern int g_var1; the variable is just declared, and later when you have to use it you can use it directly.
file1.cpp:
int g_var1;
File2.cpp:
extern int g_var1;
You need not to write extern everytime.
Though i would suggest if you have to use global variables place them in a separate header file.

How to make variable values persistent between function calls in c / c++

I have the following szenario.
I am calling functions in a DLL from a IBM Notes application (Lotusscript).
One of the functions uses type structures and we encounter problems on 64Bit.
All values in the TYPE can only be passed to the function ByRef, but I need to pass the values ByVal.
So I decided to have single arguments in the function header for every value. So far, so good. I have around 43 arguments, but LS can only handle 31 ...
Next idea was to call i.e INIT_REG_PERSON_INFO(arg1,arg2, ... ) before I make a call to the function that registers a new user.
INIT_REG_PERSON_INFO(arg1,arg2, ... );
INIT_REG_ID_INFO(arg1,arg2, ... );
REGISTER_USER();
In C, I have a function ( I know, only one argument, but it is only for testing )
/*====================================================================================*/
/* FUNCTION: BCC_InitRegPersonInfo */
/*====================================================================================*/
STATUS LNPUBLIC BCC_InitRegPersonInfo(char *FirstName){
try {
//extern char *REG_PERSON_INFO_FIRSTNAME;
memset(&reg_person_info, 0, sizeof (reg_person_info));
reg_person_info.FirstName = FirstName;
return NOERROR;
} catch (...) {
LogEventText("* BCC_InitRegPersonInfo::Exception *", NULLHANDLE, NOERROR);
return 1;
}
}
whre reg_person_info is declared as a global variable
REG_PERSON_INFO reg_person_info;
Later, in my REGISTER_USER(), I try to access the value from the global variable
LogEventText("* BCC_RegNewPerson1():reg_person_info.FirstName = %s", NULLHANDLE, NOERROR,
reg_person_info.FirstName);
But the value is always empty. I assume, the variable is deleted / reset, as soon as I exit INIT_REG_PERSON_INFO(arg1,arg2, ... );
How would I make the value persistent between function calls?
You need to create an external linkage for reg_person_info structure. In this way you are implicitly saying "I want this to be available to all units who declares it, including the main declaration unit".
In the begininning of the file where you have:
STATUS LNPUBLIC BCC_InitRegPersonInfo(char *FirstName){...}
Simply put extern typeOfReg_Person_Info reg_person_info;
by the looks of your code snippet, I am assuming that you have declared reg_person_info somewhere in a header file and #include the header file where you need? I'll update my answer once I have seen more code in the question.
A practice I have seen and used often to share global variables among units is:
/* globals.h */
#ifndef EXTERN
#define EXTERN extern
#endif
EXTERN int gMyGloablVar;
/* some-other-C-file */
#include "globals.h"
/* main.c */
#define EXTERN
#include "globals.h"
In main.c the storage is allocated; in all other compilation units they variables are declared as extern and so are known. In link time the linker fixes all references to the variables in main.

declaration in C and C++ and the habit of arranging code

I don't know what this problem belong to , Just please spend your time to read. It involves a difference about C and C++ and a habit of writing code; the code is as follows:
I divide it into 3 files;
the main.c
#include"myh.h"
unit_t *paa;
int main()
{
paa=(unit_t*)malloc(sizeof(unit_t));
if(paa==NULL){
printf("out of memory\n");
exit(1);
}
fuzhi(paa);
printf("hello !%d",paa->number);
free(paa->msg);
free(paa);
paa=NULL;
return 0;
}
anohter c: ke.c
#include"myh.h"
void fuzhi(unit_t* pa)
{
pa->number=3;
pa->msg=(char *)malloc(20);
printf("fuzhi !");
}
the h file: myh.h
#ifndef P_H
#define P_H
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct{
int number;
char *msg;
}unit_t;
void fuzhi(unit_t* pa);
int a;
#endif
So the problem is when I run the code using C it has no problem ,but when I save it as cpp, the error is multiple definiton of 'a'; why?
The second question is I don't know the habit I arrange the code is good or not. Is someone give me some good advice? When the code is big , I usually put the declaration in the h file and use a c/cpp the write the definition of the function. Then use a main c/cpp to meet the main function. Can someone give me some good advice about writing code, I am a new learner.
Thanks.
The first thing you have to remember is that C and C++ are different languages, and so have different rules about globally declared variables. And you do have the global variable a defined multiple times: Once in the main.c file and once in the ke.c file.
This is because you define the variable in the header file, which you include in both your source files. What you should do is declare the variable in the header file, and then define it in a single source file.
For example, in the header file you should have
extern int a;
And in one source file:
int a;
The compilation process as follows:
For each c. or .cpp file (called compilands):
preprocess the file, resolving all macros, #includes, etc...
compile the file, producing the object file .o. Object file contains machine code, but non-local variables are still referenced by names.
Then at the end link all object files, which includes:
resolving all the non-local variable names
replacing those with addresses
In your case, you have two compilands: main.c and ke.c.
During preprocessing, both include the .h file. As a result, both compilands declare a global variable int a. Each compiland uses its own copy of that global variable.
Then, the linker tries to resolve the names and is surprised seeing two object files defining two variables under the same name.
To solve it, in C++ header you use the keyword "extern":
extern int a;
This indicates that there will be a global variable a, but it not defines it (similarly to a function declaration without definition). In one of the compilands you then need to repeat the normal int a definition, but in a place that is not seen by other compilands (that is - not in a header)

Can I include global static member?

There are few global variables which are static in one of the header files. I see these variables are used in the associated .cc files. So, looks like this has no issues.
My questions are:
Whats the difference between including a global variable vs static global variable ?
I know static global doesnt have visibility outside its file. But dont know how this would work when it comes as part of a .h which is #included.
I wrote a sample program, and tried the same thing. But, I get compilation error the moment I make the variable static. When it is just global, it is fine.
So, is there something which I am missing on a regular g++ build ? (Please note, the initial case was on our official code base which has enough makefiles, .h files and all).
Thanks for the help !
Here is my sample program :
.h file:
#include <iostream>
typedef unsigned int uint;
static const int appk=189;
class abc1
{
public:
abc1(int x);
virtual void printVal();
};
.cc file:
#include "abc1.h"
extern int appk;
abc1::abc1(int x)
{
}
void abc1::printVal()
{
printf("abc1 print: %d\n", appk);
}
(1) If you put a global variable in a .h file and include it in various .cpp/.cc files then it will be defined multiple times for every file. So you are most like to get a linker error.
To overcome that, mostly you are likely to use extern keyword:
// myfile.h
extern int i;
and define that in only one translation unit:
// somefile.cc
int i;
(2) If you put a static global in a .h file and include it, then you will not get any error, because for every different translation unit, there will be a different copy for that static global variable.
// myfile.h
static int i; // creates a unique and unrelated copy in all .cc file where included
However, such usage is deprecated; instead of that it's better to use unnamed namespace:
namespace {
int i;
}
From your question, I don't see that you should get any linker error for static global.
Hard to tell your compilation error without code, but if you have a header that declares a static global, then you just create that global variable independently and separately in each translation unit that includes the header.
Example:
header.h:
#ifndef H_XXX
#define H_XXX
static int a;
#endif
file1.cpp:
#include "header.h"
// now have access to a variable called "a"
file2.cpp:
#include "header.h"
// now also have access to some "a"
The two files both have access to a global variable called a, but each file has its own separate copy, private to its translation unit, which is not visible outside.
For a practical example, I think cout is declared as a static global, so everyone who uses <iostream> gets their own copy.
static variable has internal-linkage. What it means is that if you have a static variable a in x.h and you include x.h in two files say m.cpp and n.pp then each of these two files gets its own copy of a which means if you change its value in m.cpp, then n.cpp is not going to see that change, because there exists two variables with same name in each translation unit (.cpp). And they're independent of each other.
But if a is not static, then including x.h in more than one files, you will get multiple-definition error, because each inclusion of x.h will try to define a, but since a is not static; it has external linkage now, which means if its defined in m.cpp, then you will get error when including x.h in n.cpp (or vice-versa). In this case, you've to write x.h as:
//x.h
extern int a;
And then define a in exactly one .cpp file, either m.cpp or n.cpp, but not both. Say its m.cpp.
//m.cpp
#include "x.h"
int a =10;
And you're done. Now you can include x.h in as many .cpp file as you want, and can access a, modify its value, do whatever you want. Any change to it, will be seen by all .cpp files now.