I have one header file that my teacher requires. I am using a global variable so I can move the value from one function to another. Looking up the problem, someone recommended using a namespace. That did not work. Additionally, I added some guards like someone else recommended, but that did not help either. I have multiple files and the commonly accepted solution of extern in header and then the declaration in the .cpp does not work for me for some reason. Global variables in header file
Methods.h
#pragma once
#define METHODS_H
#include <cfguard.h>
#ifdef METHODS_H
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
// declaring global variables
namespace global_variables
{
int number_of_employees;
}
#endif
One usage of the variable in WSCreate.cpp
// for loop to make sure amount of employees is integer
int count = 0;
int triggered = 0;
while (true){
cout << "Enter the number of employees you would like to enter\n";
string employees_in_string_format;
getline (cin, employees_in_string_format);
for (int i = 0; i < employees_in_string_format.length(); ++i)
{
triggered = 0;
if (isdigit(employees_in_string_format[i]) == false)
{
count = 1;
triggered = 1;
}
else
{
count = 0;
}
}
if (triggered == 1)
{
cout << "One of your inputs for the amount of employees you have is not a positive integer. Please enter \n positive integers\n";
}
else if (triggered == 0)
{
cout << "Your inputs are validated!\n";
number_of_employees = stoi(employees_in_string_format);
break;
}
}
WSRead.cpp (another usage of this global variable)
for (int i = 0; i != number_of_employees; i++)
{
cout << endl;
employees >> printing;
cout << printing << " ";
employees >> printing;
cout << printing << "\t ";
employees >> printing;
cout << printing << "\t\t";
employees >> printing;
cout << printing << "\t\t";
employees >> printing;
cout << printing;
cout << endl;
}
Again, sorry if it is a duplicate question, but I could not find the solution to my problem.
When exporting global variables, you want them to be defined in your c++ file so that the definition gets compiled only once by the compiler. The header file should contain a declaration of the global variable not its definition.
Currently, including the definition in the .h file adds it to all of your .obj files (built by the compiler) and the linker does not like the same variable existing at multiple places when it tries to build your .exe or library.
What you need to do is to declare the variable as extern
in the header file, and add its definition once to an appropriate .cpp file.
in the header :
extern int number_of_employee;
or if using namespace
:
namespace global_variables
{
extern int number_of_employees; // declare external global variable
}
In the .cpp
int number_of_employee;
or if using namespace
:
namespace global_variables
{
int number_of_employees; // define global variable
}
To access the global in the name space use global_variables::number_of_employees
which combines the name of the namespace, global_variables
with the name of the global variable, number_of_employees
.
Additionally, if you want to use a global variable within a .cpp file, but you don't want it to be modifiable by any external files that declare
extern int your_variable_name;
You ought to define it as "static", which means it will not be seen by the linker, and will be "private" to the .obj it's defined in.
Edit (like so):
static int your_variable_name;
Edit (as per @dxiv's comment):
Since c++17, a possibly preferred way of doing this (since it results in less bloat) is to declare your variable as inline - which tells the linker that it is allowed to have multiple declarations and, in case of variables, that all declarations should be merged as a single binary bit of data in the final binary.
inline int number_of_employee;
To make sure you have c++17 or later enabled with msvc++, you can check that you have the /std:c++17 or /std:c++latest flag in your project properties, in visual studio under
project -> properties -> Configuration properties -> General -> C++ Language Standard.
For completion sake, with the GNU or GNU-inspired compilers, you'd need the flag -std=c++17.
Have a nice evening,