What I want to do is just to define a variable in a header file and use it on two different cpp files without redefinition that variable each time I include that header
Here is how I tried :
Variables.h
#ifndef VARIABLES_H // header guards
#define VARIABLES_H
static bool bShouldRegister;
#endif
(I also tried extern but nothing changed)
And in a cpp file I give it a value ::bShouldRegister = true or bShouldRegister = true;
In my another cpp file I check it's value by creating a thread and check its value in a loop (and yes my thread function works well)
while (true)
{
if (::bShouldRegister) // Or if (bShouldRegister)
{
MessageBox(NULL,"Value Changed","Done",MB_OK|MB_ICONINFORMATION);
}
Sleep(100);
}
And yes, that MessageBox never appears (bShouldRegister never gets true :/)
You should use extern otherwise you will have separated bShouldRegister variables in each translation unit with probably different values.
Put this in a header file (.h):
extern bool bShouldRegister;
Put this in one of implementation files (.cpp):
bool bShouldRegister;
Another way which is simpler is to use inline keyword. Put you variable in a header file as below:
inline bool bShouldRegister;
If you can use C++17, consider using an inline variable:
// in a header file
inline bool bShouldRegister = true;
See How do inline variables work? for more information.
A more C++-like way would be using a class member, syntactically indicated by the static keyword. Class member variables have implicit external linkage.
#ifndef VARIABLES_H
#define VARIABLES_H
class RegUtil {
public:
static bool bShouldRegister;
};
#endif
in one of your cpp files (maybe variables.cpp), you have to define this class member:
#include "variables.h"
bool RegUtil::bShouldRegister;
You need to define the variable in one of the modules:
bool bShouldRegister;
Then declare it extern (not static!) in the header:
extern bool bShouldRegister;
Here you need to define bool bShouldRegister in one class. Your header file should like this.
#ifndef VARIABLES_H // header guards
#define VARIABLES_H
class abc{
public:
bool bShouldRegister;
abc();
#endif
Now initialize bShouldRegister variable in cpp file in constructor of abc class and then use this variable in your second cpp file using object of class. You will get your message box.
Related
I have an header file that i put some global const variables. Now I need another project wide modifiable variable. But it gives linker error as expected. I am trying to solve the issue without using inline keyword. My codes:
constants.h:
#ifndef CONSTANTS_H
#define CONSTANTS_H
namespace constants {
bool myVar;
}
#endif // CONSTANTS_H
I am using this variable in my classes with constants::myVar. And I got a linker error. Any solution without using inline (for backward compiler compability)?
I completely agree with the comments above about looking at alternatives for this design.
Also as you seems to be aware, c++17 inline variables offer a better solution.
Having said that, if you must keep the current design - you can do the following:
Change the header file to declare myVar as extern:
namespace constants {
//--vvvvvv------------
extern bool myVar;
}
Add constants.cpp file (if it doesn't exists yet), with a definition for myVar (preferably with some initialization):
namespace constants {
bool myVar;
// or better: something like:
bool myVar = false;
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why does this not prevent multiple function declarations?
Global.h
#ifndef Global_h
#define Global_h
#include <iostream>
unsigned char exitStatus;
#endif
OutputHandler.h
#ifndef OutputHandler_h
#define OutputHandler_h
#include "Global.h"
class OutputHandler {
private:
static bool instanceExists;
// more code
#endif
Root.h
#ifndef Root_h
#define Root_h
// declarations
OutputHandler *output;
#endif
Root.cpp
#include "Root.h"
// gets instance of OutputHandler
// more code
I am getting errors regarding exitStatus, static bool instanceExists, and static class output being already defined by Root.obj in OutputHandler.obj. I assume the issue is with including the header file OutputHandler.h in both Root.h and OutputHandler.cpp. Anyone know how to fix this or how to better organize header files?
Because include guards only work at the translation unit level (you can, for this simple case, consider a single C file to be a translation unit).
That means a single C file, if it includes the header file twice, will not process it the second time due to the include guards.
However, if you include the header from two different C files, each of them will get a copy of the variables defined in that header.
Then, when you link them together, you get the duplicates.
The easiest way to get around this problem is to never define things in headers, only declare them.
So, in the header (eg, xyzzy.h), you have:
extern int xyzzy; // declare but don't define.
and in all the C files that want to use that, put:
$include "xyzzy.h"
and, in one of those C files, also put:
int xyzzy; // define it here, once.
You can think of declaration as a simple "I declare that this exists somewhere, just not here", while definition is "I an creating this here and now".
Declare extern usigned char exitStatus in Global.h and define it in one implementation file.
The problem is during the linking phase; include guards in the headers won't help you.
In C, there is the separate concepts of declarations and definitions. Declarations are what are put into headers; they merely state that a particular variable exists. The definition of a variable is where storage is actually allocated for it.
For example, in your Global.h, you have:
#ifndef Global_h
#define Global_h
#include <iostream>
usigned char exitStatus;
#endif
This is defining a variable called exitStatus, and the linker is complaining because any given variable should only be defined in one place in a program. What you need to do is declare it in the header, and then define it in only one place in a source (*.cpp) file. For example, your header should declare exitStatus with:
extern char exitStatus;
and in only one source file, define it with:
char exitStatus;
The situation is similar for output in Root.h, as well as any other place you should be declaring variables in the header file.
See also: http://www.cprogramming.com/declare_vs_define.html
I have a very simple file system in a program.
There is :main.cpp which include worker.h, worker.h and worker.cpp which include worker.h
worker.h has the Header guard and has some variables declared which are required by both main.cpp and worker.cpp and it has some function declarations.
#ifndef __WORKER_H_INCLUDED__
#define __WORKER_H_INCLUDED__
bool x;
int y;
void somefunction( int w, int e );
#endif
Going through some other threads and google results, I understood that the Header guard protects you from multiple inclusions in a single source file, not from multiple source files.
So I can expect linker errors.
My question is
Why there are multiple definition errors for only variables and not for functions ? As far as my understanding goes both of those are only declared and not defined in the header file worker.h
How can I make the a variable available to both main.cpp and worker.cpp without the multiple definition linker error ?
Why there are multiple definition errors for only variables and not for functions ? As far as my understanding goes both of those are only declared and not defined in the header file worker.h
Because you defined the variables. This way they are only declared :
extern bool x;
extern int y;
But you have to define them in a cpp file. :
bool x = true;
int y = 42;
An updated answer for c++17. With the introduction of inline variables, one no longer needs to worry about the exact translation unit where non-const namespace scoped variables need to be placed. Putting aside the discussion about use of global variables in general, another way to fix the OP in modern C++ is to declare the variables as follows:
inline bool x; // Can add an initializer here too
inline int y;
So long as this is in a header and all TU's see the same exact definition, the implementation will resolve it and make sure those TU's all refer to the exact same unique object.
I'm trying to declare a class object inside a header but I can't get it working. I currently have 2 header files and 2 cpp files that defines what each function does. The classes are called Heltal and Array, and both of them are in their own header file (heltal.h and array.h).
I'm trying to declare the Heltal class object inside the private part of the Array class, but whatever I do I can't find a way to declare it. I've tried including the heltal.h header to the array.h header but then it starts complaining about being redefined.
Declaring it in the array.cpp however works just fine but I would like to have it defined in the header instead.
Here's what the files look like at the moment:
heltal.h
class Heltal {
public:
Heltal();
Heltal(int tal);
~Heltal();
void set(int tal);
bool operator < (const Heltal &heltal) const
{
return (heltal < heltal.heltal);
}
bool operator > (const Heltal &heltal) const
{
return (heltal > heltal.heltal);
}
private:
int heltal;
};
array.h
#include <vector>
class Array {
public:
Array();
Array(int in);
~Array();
int Random(int min, int max);
private:
Heltal h;
int size;
};
Both headers are included in the main.cpp
You started along the right path when you included Heltal.h inside Array.h.
Add the include guards to your headers, this will help you avoid duplicate inclusions:
#ifndef HELTAL_H
#define HELTAL_H
class Heltal {
...
};
#endif
Now you can safely include Heltal.h at the top of Array.h, and your problem will be solved.
When compile a c/cpp file, the included file would be expand in the c/cpp file first.
and some class should be in a right order.
e.g.
Heltal MUST before Array, so your include order should ensure this.
You do need to include heltal.h inside array.h, but both files will need include guards:
#ifndef array_h_guard
#define array_h_guard
// contents of array.h go here
#endif // array_h_guard
and similarly for heltal.h. This will prevent the multiple inclusion.
Note that you could simply only include heltal.h from array.h, which also fixes the immediate issue, but the include guards are safer.
I have the following code:
#ifndef GOOGLESET_PHP_H
#define GOOGLESET_PHP_H
zend_class_entry *googleset_ce;
#endif /* GOOGLESET_PHP_H */
For some reason if I include this header file in more than one cpp file, the compiler shouts that I am declaring googleset_ce more than once. Shouldn't the conditional macros above be enough to avoid this?
You need to use the extern keyword:
#ifndef GOOGLESET_PHP_H
#define GOOGLESET_PHP_H
extern zend_class_entry * googleset_ce;
#endif // GOOGLESET_PHP_H
Otherwise the compiler thinks you are declaring the variable in every file that includes this header.
This is one reason global variables are frowned upon.
yes, but you are only declaring it once per compilation unit.
include guards only make sure you declare things once per .cpp that uses it.
So if A.h is included in B.h and impl.cpp includes both, then A.h is included only the first time.
In your case, you are defining the value of the include guard macro as a static pointer variable. So even if impl.cpp has it only once, impl2.cpp which includes the same files will have them as well, so your static variable will have duplicate definitions at link-time
if you insist in having static variables (as Thomas said, it is usually bad design) it is better to wrap them in a function;
myClass* getInstance() {
static myClass instance;
return &instance;
}
this is slightly better because it makes sure the variable is truly global, some architectures (like darwin) have that static variables are unique per dynamic library, not per process, so it might led to confusing behavior/portability
Also, and more relevant, static initialization always happens before main, and the order is not guaranteed. With static function variables, the variables are initialised "on demand" and so it is not affected by initialization ordering issues
to initialise a global pointer:
myClass** getGlobalRef() {
static myClass* val;
return &val;
}
//and you set it at run-time, avoiding static-initialization happening before main
* getGlobalRef() = new myClass();
Beware that it is a linker error, not a compiler error. You get a multiple defined symbol when the linker tries to put together the object files (*.o) for all the *.cppfiles including the header file.
You would probably work around the problem using the extern keyword to make the symbol unique. And declaring it somewhere else in one (and only one) .cpp file.
instead of using "#ifndef GOOGLESET_PHP_H
#define GOOGLESET_PHP_H
#endif /* GOOGLESET_PHP_H */"
you can use
#pragma once
If the header is included in several .c/.cpp files then indeed it's potentially declared in multiple .obj files.
You have to encapsulate it in a namespace or a class so it's not considered as a global variable for each .cpp file that includes it.
lurscher has the answer. If you're looking to share the same global variable across .cpp files, one way to do it is to declare it globally in one of your .cpp files, then declare it as extern inside the header file.
For example:
main.cpp
zend_class_entry *googleset_ce = NULL;
googleset.h
#ifndef GOOGLESET_PHP_H
#define GOOGLESET_PHP_H
extern zend_class_entry *googleset_ce;
#endif /* GOOGLESET_PHP_H */