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.
Related
I'm too much confused why it's an error to write the same function in two different cpp files?
what if both want to use that function? and why this should ever cause an error, the function is written in to separate files...
a.cpp:
#include "test.h"
b.cpp:
#include "test.h"
test.h
int getMin(int x,int y)
{
return x;
}
plus, why changing test.h to the following won't fix the problem:
#ifndef UNTITLED1_A_H
#define UNTITLED1_A_H
int getMin(int x,int y)
{
return x;
}
#endif
If you define a function twice, the linker will see 2 definitions of the same function, which is not allowed. (even though each .cpp that includes this header file sees only one definition, which is why adding header guards doesn't help here).
One option is to only write the declaration of the function in the .h file, and write the definition in a separate .cpp file. (this is the more common implementation).
If you want to define the function inside the header file, then it needs to be inline, like this:
inline int getMin(int x,int y)
{
return x;
}
Note that if you do the second option, then all files that include this header will need to be recompiled, if you change the internals of this function (this is probably not a good idea, when the interface doesn't change).
You need to make this function "inline" and it will work.
I've read a lot for this problem ,but I haven't found a proper solution.
So i have 4 files:
includes.h - which contains all libraries I need in other files + some global functions
cities.h - which contains declarations of 2 classes
cities.cpp - which contains definitions of the 2 classes in cities.h
source.cpp - where is the main functon
And I have(and need) these includes
//cities.h
#include "includes.h"
//cities.cpp
#include "cities.h"
//source.cpp
#include "cities.h"
I've tried almost all combinations of #ifndef in all of the files and the program continues to give me the same error: function_X already declared in cities.obj.And this error repeats for all functions in "includes.h".
Please help me.This makes me a lot of headaches.
As you've described in the comments, you have function definitions in your includes.h header file. When this is included in multiple implementation files, you end up with multiple definitions of those functions in your program. This breaks the one definition rule. You should simply declare functions in includes.h and move their definitions into a includes.cpp file.
Something like this:
// includes.h
void foo();
int bar(int);
// includes.cpp
void foo() {
// implementation
}
int bar(int x) {
// implementation
}
I'm going to try and preempt a question that typically follows this answer. No, your include guards (#ifndef ...) are not meant to prevent this. They only prevent a header being included multiple times in a single translation unit. You are including the header in multiple translation units, which an include guard does not stop.
On top of what #sftrabbit said, If you are making a headers only library where you need to define the functions in the the header file this is possible with the keyword inline.
// includes.h
inline void foo() {
// implementation
}
inline int bar(int x) {
// implementation
}
This use of inline is not to be mistaken with its other use as a compiler suggestion to inline the function call.
I am playing around with multiple files in C++, and I have come of with the following example with does not compile:
main.cpp
#include <iostream>
#include "const.hpp"
using namespace std;
int main()
{
extern double var;
var = 5;
cout << var << endl;
return 0;
}
fct.cpp
#include <iostream>
#include "const.hpp"
using namespace std;
void func()
{
extern double var;
cout << var << endl;
}
const.hpp
#ifndef CONST_H
#define CONST_H
double var;
#endif
My program does not compile, because apparently there is a multi-definition of var. Am I correct to assume that, based on this example, a header file is not intended to be used for declaring variables as in my example above?
Instead, the correct procedure is to declare all variables in a .cpp file and use a header to tell each (relevant) translation unit that the .cpp file contains an external (extern) variable?
EDIT: Is it correct that an exeption to my rule above is when dealing with constant variables (const), which should be defined in a header?
double var; is a definition - including that header in multiple files will violate the one definition rule. If you want a global (think twice) you'll have to declare it in the header - extern double var; and move the definition to a single implementation file.
Am I correct to assume that, based on this example, a header file is not intended to be used for declaring variables as in my example above?
A header file is intended for declaring variables, but your header file defines a global variable with external linkage, and it is imported multiple times. The linker then reasonably complains about multiply defined symbols.
Instead, the correct procedure is to declare all variables in a .cpp file and use a header to tell each (relevant) translation unit that the .cpp file contains an external (extern) variable?
Yes, except that you would not be declaring the global variables in that .cpp file, but rather providing a definition for them.
const.hpp
#ifndef CONST_H
#define CONST_H
// ...
extern double var;
// ^^^^^^
#endif
globals.cpp (could be any other .cpp file, as long as it is only one)
// ...
double var;
Also, if you are wondering about the reason why your include guards won't protect you in this case, this may help you .
Is it correct that an exception to my rule above is when dealing with constant variables (const), which should be defined in a header?
In a sense, yes. Global variables qualified as const have internal linkage by default, which means that each translation unit will receive a private copy of that variable. So even when the variable's definition is included by multiple translation unit, the linker will not complain about multiply defined symbols.
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.
I have two .cpp files in one project, main.cpp and myfile.cpp
I have globaly defined struct mystruct in main.cpp, now I want to use this struct in myfile.cpp.
When I write mystruct in a header file and include in both cpp files I get an error, saying mystruct redefinition. How should I solve this problem.
If you are trying to share the definition of a struct among several compilation units (cpp files), the common way is this: Place the definition of your struct in a header file (mystruct.h). If the struct contains any methods (i.e. it is rather a class with all member public by default), you can implement them in mystruct.CPP file, or, if they're lightweight, directly within the struct (which makes them inline by default).
mystruct.h:
#ifndef MYSTRUCT_H
#define MYSTRUCT_H
struct MyStruct
{
int x;
void f1() { /* Implementation here. */ }
void f2(); /* Implemented in mystruct.cpp */
};
#endif
mystruct.cpp
#include "mystruct.h"
// Implementation of f2() goes here
void MyStruct::f2() { ... }
You can use your struct in as many cpp files as you like, simply #include mystruct.h:
main.cpp
#include "mystruct.h"
int main()
{
MyStruct myStruct;
myStruct.x = 1;
myStruct.f2();
// etc...
}
If, on the other hand, you are trying to share a global instance of the struct across several compilation units (it's not absolutely clear from your question), do as above but also add
extern MyStruct globalStruct;
to mystruct.h. This will announce that an instance is available with external linkage; in other words that a variable exists but is initialized elsewhere (in your case in mystruct.cpp). Add the initialization of the global instance to mystruct.cpp:
MyStruct globalStruct;
This is important. Without manually creating an instance of globalStruct, you'd get unresolved-external linker errors. Now you have access to globalStruct from each compilation unit that includes mystruct.h.
You should move the common struct to a header file and include that header in both files. Any other solution is a workaround.
The problem is that you basically have the same code twice as a result if you see an include as just a import of the code.
You can use #ifdef to fix it, see http://www.fredosaurus.com/notes-cpp/preprocessor/ifdef.html
Declaration and definitions are two different things. For your case, you are allocating space for your structure in main.cpp. In your header, you should use the extern modifier for your struct so that all files that include the header file will look in the global namespace for the structure. Hope it helps.
The standard C/C++ approach:
// source.h
Put all struct, class, typedef, macro definitions, extern variable declaraltions
// source.cpp
Implement the class, functions, define global/external variables
// main.cpp, and other parts of program
#include"source.h"
You should define structure in the header file only, you should remove definition from main.cpp
May be you can give more information about what is the layout of your project.
Going by the guess, probably your problem can be either of the two:
you want forward declaration of struct.
using include guards to prevent redefinition.
See the following link for how to handle both:
http://www.adp-gmbh.ch/cpp/forward_decl.html
The header files also use include guards, so you can figure out what exactly can solve your problem.
If you want to share any variable between multiple cpp files, you should declare it in header as extern. And without extern in one of that c++ files.
If you don't do it, it'll lack at linking, because multiple objects would have variable with same name. Instead when using extern one object would have this variable and other objects link it.
The header is where you declare what your struct will consist of (probably a common.h file included by main.cpp and myfile.cpp):
struct MyStruct {
int messageID;
int tempVariable;
};
In your main.cpp, this is where you actually use the struct:
void someFunction() {
struct MyStruct tempStruct;
// do something with it
tempStruct.messageID = 1;
}
Don't put the definition of your struct in both your main.h and main.cpp - or you will get a redefinition error!
Also, don't include the cpp file - include the header file (e.g. common.h). Without knowing more about the structure of your program, it is hard to provide better information.