head.h
#pragma once
namespace foo
{
int bar;
int funct1();
}
head.cpp
#include "head.h"
int foo::funct1()
{
return bar;
}
main.cpp
#include <iostream>
#include "head.h"
int main()
{
foo::bar = 1;
std::cout << foo::funct1() << std::endl;
return 0;
}
Error LNK2005 "int foo::bar" (?bar#foo##3HA) already defined in head.obj
I don't understand what is going on. I tried looking for the answer but everyone's questions are so specific to their code and don't even look close to the problem that I am having.
I am not including .cpp files into main. I am not redefining anything. I am literally just assigning 1 to the variable then returning it with a function in the same namespace. How is it being defined multiple times?
The header head.h is included in two compilation units head.cpp and main.cpp. So the variable bar is defined twice. You could declare the variable without its definition the following way
#pragma once
namespace foo
{
extern int bar;
int funct1();
}
and then define it in some cpp module.
This foo namespace-level bar declaration:
namespace foo
{
int bar;
}
is actually a definition.
To make it a declaration, mark the bar as extern in head.h:
namespace foo
{
extern int bar;
}
Then define it in head.cpp:
int foo::bar = 0;
head.h is included in both main.cpp and head.cpp.
So the variable is defined twice.
Possible Solution: make it inline. The "extern" solutions are also good, although older in approach.
namespace foo
{
inline int bar;
}
How is it being defined multiple times?
It is defined once in head.cpp and once in main.cpp. That is a total of two times. This violates the one definition rule, which states that there may only be one definition for every variable.
int bar;
This is a definition of a variable. You've included it into two translation units.
A variable can be declared without definition in an extern declaration:
extern int bar;
Replace the definition with such declaration, and put the definition into exactly one translation unit.
I am not redefining anything. I am literally just assigning 1 to the variable
You're redefining the variable!
head.cpp has one via #include "head.h", and main.cpp has one via #include "head.h".
You need to merely declare it (unusual but not too strange) in the header:
extern int bar;
…then define it in one translation unit. This is just like what you do with static class members (albeit with slightly different syntax).
Since C++17, you may do this by instead plopping the inline keyword on to your definition.
Alternatively, avoid mutable globals…
Do carefully note that foo is not a class, but a namespace. When you declare a free variable in the header file:
int bar;
And then #include this header file multiple times (into different CPP files, causing multiple translation unit compilations), you'd get a linker error. Everyone knows it.
And, you'd add extern attribute at the declaration, and define the variable elsewhere in one of the CPP/C file.
Putting a global variable into a namespace is nothing but giving the global variable a different name. Think if foo::bar as foo__NS__bar, and hence you must add extern in the header and define foo::bar at some locatoin.
Note that this is different from a non-static member variable of a class. A class variable doesn't need to be defined/declared this way since the class is a type. Each instantiated variable of class-type would have a separate copy of the variable.
Further to that, when you add a static variable in the class, you are giving that logically global variable another name. Thence, you must have that static-variable defined one of the CPP file.
Related
There is one variable called BOT_TIME that varies with the difficulty of my game, and hence isn't const. There are many files that use it. I intend to use it as a global variable.
1) In constants.h I declare it extern int BOT_TIME.
In constants.cpp, I declare it extern int BOT_TIME.
BUILD => undefined references to the variable in all sources(Yes, I've included the header).
2) In constants.h I declare it int BOT_TIME.
In constants.cpp, I declare it int BOT_TIME.
Since non-consts are by default extern , I decided to leave that keyword.
BUILD => Multiple definition of the variable (shows in each source file that has constants.h included)
3) In constants.h I declare it extern int BOT_TIME.
In constants.cpp, I declare it int BOT_TIME.
This works.
Where is the issue?
Initializing the variable to something in constants.cpp makes it work for cases 1 and 3.
What is this happening?
Which is the right approach?
You can declare a variable as many times as you want, you can and have to define it only once.
extern int BOT_TIME;
is a declaration.
int BOT_TIME;
is a definition.
The definition has to appear in a single implementation file.
Since non-consts are by default extern , I decided to leave that keyword.
Nope. How'd you figure?
To answer the questions:
1) There's no definition, only declarations.
2) The assumption is wrong. You define the symbol multiple times.
3) It works because that's the correct way to do it.
From the comments:
When you declare a variable with extern, you specify that it has external linkage, yes, but you only declare, and not define it. If you leave it without the extern keyword, it still has external linkage, but it's also a definition.
You need to declare the variable in a header file and define it once and only once in a source file.
The correct way to do this is:
constants.h
//declare the symbol as extern
extern int BOT_TIME;
constants.cpp
#include "constants.h"
//define the symbol once and only once
int BOT_TIME;
XXXX.cpp
#include "constants.h"
//Include the header file which declares it extern in any source file
//you want to access it
//use BOT_TIME
You can declare a variable as many times but you can only define it once.
If you define a variable more than once you violate the One Definition Rule.
extern int BOT_TIME;
is a declaration and #1 only makes the same declaration twice, this is allowed but it doesn't work since you never define the variable.Note that every extern variable must be defined once or the compiler cannot find its definition and hence complains.
In #2 you define the same symbol multiple times in different translation units.This violates the One Definition rule and hence the linker reports the same.
#3 is the correct way to do it.
Good Read:
What is the difference between a definition and a declaration?
extern int x; // declaration
int x; // definition
extern int x = 3; // definition
In general, you need a declaration in the header file, for source files that need to know about x. You need one definition, in one source file, so that there is actually an object x.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is external linkage and internal linkage in C++
Actually I want to know the importance of extern.
First I wrote some code :
file1.h
extern int i;
file2.c
#include<stdio.h>
#include "file1.h"
int i=20;
int main()
{
printf("%d",i);
return 0;
}
Now my question is that: what is the use of extern variable when I have to define the i in file2.c, declaring in file1.h is in which way useful to me .
sudhanshu
extern allows you to declare a variable (notify the compiler of its existence) without defining it (bringing it into existence). The general rule is that you can declare things as many times as you want, but you can only define them once.
This is useful if, for example, it will be defined elsewhere.
Consider:
file1.c: file2.c:
extern int xyzzy; int xyzzy;
void fn (void) {
xyzzy = 42;
}
When you link together those two functions, there will be one xyzzy, the one defined in file2.c, and that's the one that fn will change.
Now that happens even without the extern. What the extern does is to declare that xyzzy exists to file1.c so that you don't get any I don't know what the blazes "xyzzy" is errors.
In your particular case (if those are your only two files), you don't need it. It's only needed if you had another file that #included file1.h and tried to access i.
It's useful when you have three files:
foo.h
extern int i;
void bar();
a.c:
#include "foo.h"
int i = 6;
int main(){
bar();
}
b.c:
#include "foo.h"
void bar(){
printf("%d\n", i);
}
As you can see, i is shared between both a.c and b.c, not redefined per-file, as would happen without the extern keyword.
The "extern" declaration in C is to indicate that there is an existence of, and the type of, a global variable.
In C mostly each .c file behaves like a seperate module. Hence a variable with "extern" is something that is defined externally to the current module.
It is always a better practise to define the global in one place, and then declare extern references to it in all the other places. When refering to globals provided by any shared library, this is important in order to make sure that your code is referring the correct and common instance of the variable.
From Wikipedia:
When a variable is defined, the compiler allocates memory for that
variable and possibly also initializes its contents to some value.
When a variable is declared, the compiler requires that the variable
be defined elsewhere. The declaration informs the compiler that a
variable by that name and type exists, but the compiler need not
allocate memory for it since it is allocated elsewhere.
Extern is a way to explicitly declare a variable, or to force a
declaration without a definition
If a variable is defined in file 1, in order to utilize the same
variable in another file, it must be declared. Regardless of the
number of files, this variable is only defined once, however, it must
be declared in any file outside of the one containing the definition.
If the program is in several source files, and a variable is defined
in file1 and used in file2 and file3, then extern declarations are
needed in file2 and file3 to connect the occurrences of the variable.
Having extern tells the compiler its a declaration of a variable.
In your example in file1.h imagine what would happen if you didn't specify extern keyword. It will look like there are two definitions of int i. Also, a header file can be included in many .c files. If you compile those .c files and link them, linker would see multiple definitions of the same variable.
extern keyword allows you to say to the compiler ... " Use this variable right now .. I will define and initialize it later ".. i.e " Compile it now .. I will link to its definition later".
You can extern the variable when you define it in some other file and you want to use it in the current context..
The declaration in the header allows you to access the variable from more than one source file, while still only defining it in one place.
I know one should not use global variables but I have a need for them. I have read that any variable declared outside a function is a global variable. I have done so, but in another *.cpp file, that variable could not be found. So it was not really global. Isn't it so that one has to create a header file GlobalVariabels.h and include that file to any other *cpp file that uses it?
I have read that any variable declared outside a function is a global variable. I have done so, but in another *.cpp File that variable could not be found. So it was not realy global.
According to the concept of scope, your variable is global. However, what you've read/understood is overly-simplified.
Possibility 1
Perhaps you forgot to declare the variable in the other translation unit (TU). Here's an example:
a.cpp
int x = 5; // declaration and definition of my global variable
b.cpp
// I want to use `x` here, too.
// But I need b.cpp to know that it exists, first:
extern int x; // declaration (not definition)
void foo() {
cout << x; // OK
}
Typically you'd place extern int x; in a header file that gets included into b.cpp, and also into any other TU that ends up needing to use x.
Possibility 2
Additionally, it's possible that the variable has internal linkage, meaning that it's not exposed across translation units. This will be the case by default if the variable is marked const ([C++11: 3.5/3]):
a.cpp
const int x = 5; // file-`static` by default, because `const`
b.cpp
extern const int x; // says there's a `x` that we can use somewhere...
void foo() {
cout << x; // ... but actually there isn't. So, linker error.
}
You could fix this by applying extern to the definition, too:
a.cpp
extern const int x = 5;
This whole malarky is roughly equivalent to the mess you go through making functions visible/usable across TU boundaries, but with some differences in how you go about it.
You declare the variable as extern in a common header:
//globals.h
extern int x;
And define it in an implementation file.
//globals.cpp
int x = 1337;
You can then include the header everywhere you need access to it.
I suggest you also wrap the variable inside a namespace.
In addition to other answers here, if the value is an integral constant, a public enum in a class or struct will work. A variable - constant or otherwise - at the root of a namespace is another option, or a static public member of a class or struct is a third option.
MyClass::eSomeConst (enum)
MyNamespace::nSomeValue
MyStruct::nSomeValue (static)
Declare extern int x; in file.h.
And define int x; only in one cpp file.cpp.
Not sure if this is correct in any sense but this seems to work for me.
someHeader.h
inline int someVar;
I don't have linking/multiple definition issues and it "just works"... ;- )
It's quite handy for "quick" tests... Try to avoid global vars tho, because every says so... ;- )
If you want to put function definitions in header files, it appears there are three different solutions:
mark the function as inline
mark the function as static
put the function in an anonymous namespace
(Until recently, I wasn't even aware of #1.) So what are the differences to these solutions, and when I should I prefer which? I'm in header-only world, so I really need the definitions in the header files.
The static and unnamed namespace versions end up being the same: each Translation Unit will contain it's own version of the function, and that means that given a static function f, the pointer &f will be different in each translation unit, and the program will contain N different versions of f (more code in the binary).
This is not the right approach to provide a function in a header, it will provide N different (exactly equal) functions. If the function contains static locals then there will be N different static local variables...
EDIT: To make this more explicit: if what you want is to provide the definition of a function in a header without breaking the One Definition Rule, the right approach is to make the function inline.
As far as I know, only inline and template functions can be defined in header files.
static functions are deprecated, and functions defined in an unnamed namespace should be used instead (see 7.3.1.1 p2). When you define a function in an unnamed namespace in a header, then every source code including that header (directly or indirectly) will have an unique definition (see 7.3.1.1 p1). Therefore, functions should not be defined in the unnamed namespace in header files (only in source files).
The standard referenced are from the c++03 standard.
EDIT:
Next example demonstrates why functions and variables shouldn't be defined into unnamed namespace in headers :
ops.hpp contains:
#ifndef OPS_HPP
#define OPS_HPP
namespace
{
int a;
}
#endif
dk1.hpp contains:
#ifndef DK1_HPP
#define DK1_HPP
void setValue();
void printValue();
#endif
dk1.cpp contains:
#include "dk1.hpp"
#include "ops.hpp"
#include <iostream>
void setValue()
{
a=5;
}
void printValue()
{
std::cout<<a<<std::endl;
}
dk.cpp contains :
#include "dk1.hpp"
#include "ops.hpp"
#include <iostream>
int main()
{
// set and print a
setValue();
printValue();
// set and print it again
a = 22;
std::cout<<a<<std::endl;
// print it again
printValue();
}
Compile like this:
g++ -ansi -pedantic -Wall -Wextra dk.cpp dk1.cpp
and the output :
5
22
5
ops the variable a is different for the source file dk1.cpp and dk.cpp
static functions (equivalent to anonymous namespace) receive different copies for each TU. If the function is re-entrant this is basically identical (some compilers might have assembly-level differences) but if it isn't then it will have different static data for each TU. Inline functions are folded- that is, they have only one copy of static data for every TU.
You could consider wrapping the methods in a class instead of a namespace. Declare these methods as static and delete the constructor of the class to reinforce that this is not an object to be instantiated.
struct FooNamespace
{
FooNamespace() = delete;
static FooMethod1() {
...
}
static FooMethod2() {
...
}
};
You get the same general behavior as it belonging to a namespace with only a single implementation.
In the header I declared
#ifndef SOUND_CORE
#define SOUND_CORE
static SoundEngine soundEngine;
...
but the constructor for SoundEngine gets called multiple times, how is it possible, when it's declared as global static
I call it as
#include "SoundCore.h"
and use it directly
soundEngine.foo()
thank you
I would use extern instead of static. That's what extern is for.
In the header:
extern SoundEngine soundEngine;
In an accompanying source file:
SoundEngine soundEngine;
This will create one translation unit with the instance, and including the header will allow you to use it everywhere in your code.
// A.cpp
#include <iostream>
// other includes here
...
extern int hours; // this is declared globally in B.cpp
int foo()
{
hours = 1;
}
// B.cpp
#include <iostream>
// other includes here
...
int hours; // here we declare the object WITHOUT extern
extern void foo(); // extern is optional on this line
int main()
{
foo();
}
A copy of static variables declared in header files gets created for each translation unit where you include the header.
Never declare your static variables inside header files.
You could use a singleton object.
As others mentioned in the answers, static variable in header file gets included in every file where the the header is included. If you want to still keep it static and avoid multiple instantiations then wrap it in a struct.
//SoundCore.h
struct Wrap {
static SoundEngine soundEngine;
};
Now define this variable in one of the .cpp files.
//SoundCore.cpp
SoundEngine Wrap::soundEngine;
And use it simply as,
Wrap::soundEngine.foo();
If you include this header file in multiple files, your class will be instantiated for every inclusion. I think you better take a look at Singleton pattern, to get only 1 instance, i.e., just one constructor call.
As many other reserved words, static is a modifier that has different meanings according with the context.
In this case, you are creating an object of the class SoundEngine which is private in this module. This means that it is not visible from other modules.
However, you put this line in the header, so it is a private object in various modules. I guess that's the reason of the constructor being called multiple times.