This question already has answers here:
How to initialize private static members in C++?
(18 answers)
Closed 8 years ago.
So, let's say I have a header like this:
#ifndef BASECLASS_H
#define BASECLASS_H
class BaseClass
{
public:
static int getX(){return x;}
private:
static int x;
};
int BaseClass::x = 10;
#endif
I have heard many times that I should not initialise static variables inside a header, but rather in cpp. But as there are guards, there should be only one copy of BaseClass::x. So I kinda do not understand why I should put
int BaseClass::x = 10;
in cpp.
If you do it in the header, you'll get multiple definition errors as soon as you include it from more than one CPP file. You're really telling the compiler two things when you declare
int BaseClass::x = 10;
First, you're defining the symbol BaseClass::x; second you're telling it you want it to have the initial value of 10. According to the One Definition Rule this can only happen once in your program.
Maybe it's easier to understand if you think about what the preprocessor actually does: It copies the content of all included header files into the cpp file and passes this to the compiler.
Now let's say you have:
// In a.cpp
#include <baseclass.h>
// more code
// In b.cpp
#include <baseclass.h>
// more code
After the preprocessor expands the includes, both files will contain:
int BaseClass::x = 10;
Now as soon as both object files are passed to the linker, it will see the symbol BaseClass::x twice - which is an error.
Now, to make it even more obvious, imagine you would put this in a header file:
int aGlobalVariable = 10;
And then include it in two different cpp files, which should both be linked into one executable. It's actually not any different from your example, if seen from the linker's point of view.
Why is this not a problem with class declarations?
There's a difference between declarations and definitions. Only the latter will cause problems. E.g., all of the following are declarations:
extern int a;
void foo(int a);
class Foo { int bar(); };
Whereas these are definitions:
int a;
int b = 10;
void foo(int a) { /*..*/ }
int Foo::bar() { /*...*/ }
As long as there is one (and only one) definition, you can have as many declarations as you'd like, and the linker will make sure they all refer to the same function or memory location.
Now what about classes? Classes can only be declared, while their member functions and static members have to be defined. Again, each definition may only exist once.
Member functions and static members actually exist only once in a program's address space, whereas normal members (instance variables) exist for each object of the class.
Getting back to your specific problem: static members are basically just global variables, but scoped to the class' name.
Hope this clears things up for you!
The guards do not prevent multiple copies in multiple source files. They only prevent multiple copies in one source file.
You will be violating the one definition rule if you have multiple source files that #include "base_class.h".
Because If you initialize it in the header there is a possibility that it would be defined in multiple locations if you include the header more than once. Which will result in a linker error
Related
Disclaimer: This is probably a basic question, but I'm a theoretical physicist by training trying to learn to code properly, so please bear with me.
Let's say that I want to model a fairly involved physical system. In my understanding, one way of modelling this system is to introduce it as a class. However, since the system involved, the class will be large, with potentially many data members, member functions and subclasses. Having the main program and this class in one file will be very cluttered, so to give a better overview of the project I tend to put the class in a separate .h file. Such that I'd have something like:
//main.cpp
#include "tmp.h"
int main()
{
myclass aclass;
aclass.myfunction();
return 0;
}
and
// tmp.h
class myclass
{
// data members
double foo;
double bar;
public:
// function members
double myfunction();
};
double myclass::myfunction()
{
return foo + bar;
}
This however, amounts to the following compiler warning in my new compiler: function definitions in header files can lead to ODR violations. My question then is this: what is actually the preferred way of dealing with a situation like this? I guess I can just make tmp.h into tmp.cpp, but to the best of my understanding, this is the intended use of .h files?
Normally, a class definition goes in an ".h" file and its member functions' definitions go in a ".cpp" file.
If you want to define member functions in the header, you need to either declare them inline, or write them inside the class definition (which makes them implicitly inline).
Adding to the other answers:
This is a function definition:
double myfunction()
{
return foo + bar;
}
This is a function declaration:
double myfunction();
The purpose of the declaration is to declare the unique signature of the function to other code. The function can be declared many times, but can only have one definition, hence the ODR (One Definition Rule).
As a basic rule to start with, put function declarations in header files, and put definitions in source files.
Unfortunately in C++, things rapidly get more complicated.
The problem with just having the function signature available is that you can't easily optimise the code in the function, because you can't see it. To solve that problem, C++ allows function definitions to be put in headers in several circumstances.
You'll have to either use the inline keyword or put the definition of myclass in a .cpp file.
myclass.hpp
#ifndef MY_CLASS_H
#define MY_CLASS_H
class myclass
{
public:
double myfunction( );
private:
double foo;
double bar;
};
#endif
myclass.cpp
#include "myclass.hpp"
double myclass::myFunction( )
{
return foo + bar;
}
Or you can define the function in the header (myclass.hpp) using inline.
#ifndef MY_CLASS_H
#define MY_CLASS_H
class myclass
{
public:
double myfunction( );
private:
double foo;
double bar;
};
inline double myclass::myFunction( )
{
return bar + foo;
}
#endif
If you define the myFunction function in the class declaration then you can omit the use of the inline keyword.
#ifndef MY_CLASS_H
#define MY_CLASS_H
class myclass
{
public:
double myfunction( )
{
return foo + bar;
}
private:
double foo;
double bar;
};
#endif
ODR stands for One Definition Rule. It means that everything should have one and only one definition. Now, if you define a function in a header file, every translation unit that includes that header file will get a definition. That obviously violates the ODR. That's what the compiler is warning about. You have couple of ways to work around that:
Move the function declaration to a cpp file. That way there is a single definition.
Make the function inline. This means that there may be multiple definitions of this function, but you're sure that all are identical and the linker may use one those and ignore the rest.
Make the function static (doesn't apply to class-methods). When a function is static each translation unit gets it's own copy of the method, but they are all different functions and belong to one and only one compilation unit. So it's OK.
My 'Headers.h' file includes basic c++ Headers
#include <iostream>
#include <cstring>
// and many header files.
wrote a function definition for file exist check and saved it in 'common_utility.h' - ifFileExist()
common_utility.h
bool ifFileExist()
{
// ... My code
}
Wrote code for Class A
classA.h
class A
{
// Contains class A Declarations.
};
classA.cpp
// Contains
#include "Headers.h"
#include "common_utility.h"
#include "classA.h"
// class A Method definition
Wrote Code for Class B
I am using class A in Class B.
classB.h
class B
{
// Contains class A Declarations.
}
classB.cpp
// Contains
#include "Headers.h"
#include "common_utility.h"
#include "classA.h"
#include "classB.h"
// class B Method definition
// calling the function ifFileExist() in class B also.
wrote code for main program
main.cpp
// Contains
#include "Headers.h"
#include "common_utility.h"
#include "classA.h"
#include "classB.h"
// I am using class A and Class B in main program
// calling the function ifFileExist() in Main program also.
When I compile the whole program as
g++ -std=c++0x classA.cpp classB.cpp main.cpp -o main
I am getting the following error.
In function ifFileExist()': classB.cpp:(.text+0x0): multiple
definition ofifFileExist()'
/tmp/ccHkDT11.o:classA.cpp:(.text+0x2b6e): first defined here
So I decleard ifFileExist() function in Headers.h as extern.
extern bool ifFileExist();
But still I am getting the same error.
I am including 'Headers.h' in every .cpp file. That file contains basic c++ libraries. But I didn't get any mulitple definition error for that header files.
But only in my own function, I am getting the error 'multiple definition'.
I want to use 'common_utility.h' file, when ever I need to use it. If I doesn't need to use the common_utility functions in my main program, simply I should not include it.
I want my program to run in the every following cases.
g++ -std=c++0x classA.cpp main.cpp -o main
g++ -std=c++0x classB.cpp> main.cpp -o main
g++ -std=c++0x classA.cpp classB.cpp main.cpp -o main
I shouldn't get mulitple definition error at any cases. What Should I do now?
Since I could not find any complete (in my view) duplicate for this question, I am going to write a (hopefully) authoritive and complete answer.
What is One Definition Rule and why should I care
A One Definition Rule, usually dubbed ODR, is a rule which states (simplified) that any entity (informal term) used in the program should be defined once, and only once. An entity which is defined more than once is often causing a compilation or linker error, but sometimes can be left undetected by the compiler and lead to very hard-to-trace bugs.
I am not going to formally define entity here, but one can think of it as a function, variable or class. Before going further, one should very clear understand the difference between definition and declaration in C++, since while double definition is prohibited, double declaration is usually unavoidable.
Definition vs. declaration
Every entity used in the code should be declared in the given translation unit (translation unit is usually a cpp source file together with all header files included in it, directly or indirectly through other header files). The way an entitty is declared differes based on the entity itself. See below on how to declare different types of entities. Entities are often declared in header files. Since most complex application has more than one translation unit in it (more than one cpp file), and different cpp files often include the same headers, an application is likely to have multiple declarations for many entities used. Like I said above, this is not a problem.
Every entity used in the application, must be defined once and only once. The term 'application' is used a bit loosely here - for example, libraries (both static and dynamic) can have entities (at this point usually called symbols) left undefined within them, and an executable which was linked to use a dynamic library can have a symbol undefined as well. Instead, I refer to the application is an ultimate running something, after all the libraries have been statically or dynamically linked into it, and symbols resolved.
It is also worth noting that every definition serves as a declaration as well, meaning, that whenever you define something, you are also declaring the same thing.
As with declaration, the way to define an entity differes by the type of entity. Here is how one can declare/define 3 basic types of entities - variables, classes and functions - based on it's type.
Variables
Variables are declared using following construct:
extern int x;
This declares a variable x. It does not define it! A following piece of code will be compiled OK, but an attempt to link it without any other input files (for example, with g++ main.cpp) will produce a link-time error due to undefined symbols:
extern int x;
int main() {
return x;
}
The following piece of code defines variable x:
int x;
If this single line were to be put into file x.cpp, and this file compiled/linked together with main.cpp from above with g++ x.cpp main.cpp -o test it would compile and link without problems. You could even run resulting executable, and if you are to check exit code after the executable was run, you'd notice it is 0. (Since global variable x would be default-initialized to 0).
Functions
Functions are declared by providing their prototypes. A typical function declaration looks like following:
double foo(int x, double y);
This construct declares a function foo, returning double and accepting two arguments - one of type int, another of type double. This declaration can appear multiple times.
Following code defines above mentioned foo:
void foo(int x, double y) {
return x * y;
}
This definition can only appear once in the whole application.
Function definition has an additional quirk to variable definition. If above definition of foo were to put into header file foo.h, which in turn would be included by two cpp files 1.cpp and 2.cpp, which are compiled/linked together with g++ 1.cpp 2.cpp -o test you would have a linker error, saying that foo() is defined twice. This might be prevented by using following form of foo declaration:
inline void foo(int x, double y) {
return x * y;
}
Note inline there. What it tells compiler is that foo can be included by multiple .cpp files, and this inclusion should not produce linker error. Compiler have several options on how to make this happen, but it can be relied upon to do it's job. Note, it would still be an error to have this definition twice in the same translation unit! For example, following code will produce a compiler error
inline void foo() { }
inline void foo() { }
It is worth noting, that any class method defined within the class is implictly inline, for example:
class A {
public:
int foo() { return 42; }
};
Here A::foo() is defined inline.
Classess
Classess are declared by following construct:
class X;
Above declaration declares class X (and at this point X is formally called an incomplete type), so that it can be used when information about it contents, such as it's size or it's members is not needed. For example:
X* p; // OK - no information about class X is actually required to define a pointer to it
p->y = 42; // Error - compiler has no idea if X has any member named `y`
void foo(X x); // OK - compiler does not need to generated any code for this
void foo(X x) { } // Error - compiler needs to know the size of X to generate code for foo to properly read it's argument
void bar(X* x) { } // OK - compiler needs not to know specifics of X for this
A definition of class is well-known to everybody, and follows this construct:
class X {
public:
int y;
};
This makes a class X defined, and now it can be used in any context. An important note - class definition has to be unique per tralnlation unit, but does not have to be unique per application. That is, you can have X defined only once per translation unit, but it can be used in multiple files linked together.
How to properly follow ODR rules
Whenever a same entity is defined more than once in the resulting application, so-called ODR violation happenes. Most of the time, a linker will see the violation and will complain. However, there are cases when ODR violation does not break linking and instead causes bugs. This might happen, for example, when the same .cpp file defining a global variable X is put into both application and dynamic library, which is loaded on demand (with dlopen). (Yours trully spent a couple of days trying to trace a bug happened because of that.)
A more conventional causes of ODR violations are:
Same entity defined twice in the same file in the same scope
int x;
int x; // ODR violation
void foo() {
int x;
} // No ODR violation, foo::x is different from x in the global scope
Prevention: don't do this.
Same entity defined twice, when it was supposed to be declared
(in x.h)
int x;
(in 1.cpp)
#include <x.h>
void set_x(int y) {
x = y;
}
(in 2.cpp)
#include <x.h>
int get_x() {
return x;
}
While the wisdom of above code is questionable at best, in serves a point of illustrating ODR rule. In the code above, variable x is supposed to be shared between two files, 1.cpp and 2.cpp, but was coded incorrectly. Instead, the code should be following:
(in x.h)
extern int x; //declare x
(in x.xpp)
int x; // define x
// 1.cpp and 2.cpp remain the same
Prevention
Know what you are doing. Declare entities when you want them declared, do not define them.
If in the example above we'd use function instead of the variable, like following:
(in x.h)
int x_func() { return 42; }
We would have a problem which could be solved in two ways (as mentioned above). We could use inline function, or we could move definition to the cpp file:
(in x.h)
int x_func();
(in x.cpp)
int x_func() { return 42; }
Same header file included twice, causing the same class defined twice
This is a funny one. Imagine, you have a following code:
(in a.h)
class A { };
(in main.cpp)
#include <a.h>
#include <a.h> // compilation error!
The above code is seldom appearing as written, but it is quite easy to have the same file included twice through the intermediate:
(in foo.h)
#include <a.h>
(in main.cpp)
#include <a.h>
#include <foo.h>
Prevention Traditional solution to this is to use so-called include guards, that is, a special preprocessor definitions which would prevent the double-inclusion. In this regard, a.h should be redone as following:
(in a.h)
#ifndef INCLUDED_A_H
#define INCLUDED_A_H
class A { };
#endif
The code above will prevent inclusion of a.h into the same translation unit more than once, since INCLUDED_A_H will become defined after first inclusion, and will fail #ifndef on all subsequent ones.
Some compilers expose other ways to control inclusion, but to date include guards remain the way to do it uniformely across different compilers.
Before actually compiling source the compilation unit is generated from .cpp files. This basically means that all preprocessor directives are computed: all #include will be replaces with content of the included files, all #define'd values will be substituted with corresponding expressions, all #if 0 ... #endif will be removed, etc. So after this step in your case you'll get two pieces of C++ code without any preprocessor directives that will both have definition of same function bool ifFileExist() that is why you get this multiple definition error.
The fast solution is to mark it as inline bool ifFileExist(). Basically you ask compiler to replace all corresponding function calls with content of the function itself.
Another approach is to live the declaration of your function in common_utility.h and move definition to common_utility.cpp
Consider the following four member function declarations and definitions:
// ==== file: x.h
#ifndef X_H
#define X_H
class X {
public:
int a(int i) { return 2 * i; }
inline int b(int i) { return 2 * i; }
int c(int i);
int d(int i);
};
inline int X::c(int i) { return 2 * i; }
int X::d(int i) { return 2 * i; }
#endif
For completeness, here's the .cpp file that instantiates an X and calls the methods...
// ==== file: x.cpp
#include "x.h"
#include <stdio.h>
int main() {
X x;
printf("a(3) = %d\n", x.a(3));
printf("b(3) = %d\n", x.b(3));
printf("c(3) = %d\n", x.c(3));
printf("d(3) = %d\n", x.d(3));
return 0;
}
My question: are there any salient differences among the four methods? I understand from a comment in this post that the compiler may automatically inline methods that are defined in the class definition.
update
Many answers assume that I'm asking about the difference between inlining and not. I'm not. As I mentioned in the original post, I understand that defining a method in the header file gives the compiler license to inline the method.
I also (now) understand that method d is is risky as written: since it is not inlined, it will be multiply defined if there are multiple translation units.
My question remains: are there any salient differences among the four methods? (As noted, I know that method d is different). But -- just as important -- are there stylistic or idiomatic considerations that would make a developer choose one over the others?
Since this answer keeps getting upvotes, I feel obligated to improve it. But much of what I'm adding has already been stated in other answers and comments, and those authors deserve the credit.
On the subject of whether there's a difference between placing a function body inside the class definition or just below it (but still in the header file), there are 3 different cases to think about:
1) The function is not a template and is not declared to be inline. In this case it must be defined in the class definition or a separate cpp or you will get a linker error as soon as you try to include the h in more than one compilation unit.
2) The function is a template, but is not declared inline. In this case, putting the body within the class definition provides a hint to the compiler that the function can be inlined (but the final decision is still at its own discretion).
3) The function is declared to be inline. In this case there is no semantic difference, but it may sometimes be necessary to place the function body at the bottom in order to accommodate dependency cycles.
Original answer, which provides good info but does not address the actual question:
You've already noted the inline difference. In addition, defining member functions in the header means your implementation is visible to everyone. More importantly, it means everyone who includes your header also needs to include everything needed to make your implementations work.
If you are going to inline it regardless, then you'd move it out of the class if you want to be able to see all your members in one screen, or you have a cyclic dependency as mentioned below. If you don't want to inline it, then you have to move it out of the class and into an implementation file.
In the cases of classes that cyclically refer to each other, it may be impossible to define the functions in the classes so as to inline them. In that case, to achieve the same effect, you need to move the functions out of the classes.
Doesn't compile:
struct B;
struct A {
int i;
void foo(const B &b) {
i = b.i;
}
};
struct B {
int i;
void foo(const A &a) {
i = a.i;
}
};
Does compile, and achieves the same effect:
struct B;
struct A {
int i;
inline void foo(const B &b);
};
struct B {
int i;
inline void foo(const A &a);
};
inline void A::foo(const B &b) {
i = b.i;
}
inline void B::foo(const A &a) {
i = a.i;
}
Oops, just realised you had the definitions in the header file. That creates problems if the include file is included in more than one place.
If the functions are defined in a CPP file then there is no difference.
The only time it makes sense to implement a function inline is when the function is very clearly trivial and/or it has performance implications.
For all other times, it's best to put them in a .cc file and keep its implementation not exposed to the user of the class.
As pointed out by user3521733, it is impossible to implement some functions in the header file when there are cyclic dependencies. Here you are forced to put the implementations in a .cc file.
Update
As far as the compiler, and the runtime, is concerned, there is no difference that I can think of between defining the function inside the body of the class or outside if you use inline when defining it outside the body of the class.
X::a, X::b and X::c are all inlined. X::d is not. That's the only real differnce between these functions, aside from the fact that they are all different functions. The fact that X::c is defined in the header is irrelevant. What is relevant there is that the definition is marked inline.
In order to understand what the differences are, it's important to understand what inline is and is not. inline is not a performance tweak. It's not about making your code faster, and it's not about blowing the code out inline.
What it is about is the ODR. A function marked inline will have the exact same definition in each translation unit where it is used.
This comes in to play when you try to #include your file above in two or more CPP files and call X::d in those translation units. The linker will complain that X::d is defined more than once -- you've violated the ODR. The fix to this is to either mark the function inline or move the definition to it's own translation unit. (eg, to a CPP file)
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Static variables in C++
// x.h
int i = 3;
// x1.cpp
#include"x.h"
//...
// x2.cpp
#include"x.h"
//...
Above code will give linker error. However If I declare,
//x.h
static int i = 3;
It doesn't give linker error in gcc, even we have the same #include! Are we creating different static int i; for every .cpp file ? Will it cause any silent linking bug (due to same name)?
When C code is compiled, it's one "translation unit" at a time. Early on, #includes are expanded into the text of the referenced files. So what you've got in the static case is equivalent to x1.cpp saying static int i = 3; and x2.cpp doing the same. And static in this context means roughly "don't share this with other translation units."
So yes, when you use static there you are making two different i variables which have nothing to do with each other. This will not cause a linking error.
int x; is a definition of the entity x. The One Definition Rule of C++ says that any variable that is used shall be defined exactly once in the program. Hence the error.
static says that x has internal linkage. That is, the x's that appear in one.cpp and two.cpp are two different unrelated entities.
The C++ standard says that the use of static in this case is deprecated(As per Steve's comment, in C++0x it's undeprecated). Anonymous namespaces provide a superior alternative.
namespace
{
int x;
}
Also note that unlike C, in C++ const variables of scalar types also have internal linkage. That is
const int x = 7; // won't give you an error if included in different source files.
HTH
Are we creating different static int i; for every .cpp file ?
Yes
Will it cause any silent linking bug (due to same name)?
No. Due to static, they have different names.
If this isn't the behavior you want, you need to use extern in the header file, and allocate the variable in one translation unit (.cpp file)
static creates a global variable that is only visible inside the unit.
If you want to use a variable in more than on ecompilation unit, use extern in the header and declare it in the implmenetation without extern.
You get the linker error in your first code example because i is defined and exported in both compilation units. In the second case i is static, so there is no exported symbol because static variables are only visible in the current compilation unit and aren't exported to the linker. In this case you have two independent variables that are both called i.
As written, the code looks like the same i is being accessed by multiple .cpp files, whereas in reality, each .cpp file will have its own copy. This can lead to misunderstandings and bugs.
If you want there to be just one copy of i, the preferred idiom is to wrap it in an accessor function in x.h:
int& GetI() {
static int i = 3; // this initialization only happens once.
return i;
}
If you do want separate copies of i for each .cpp file, a much clearer expression of this is to simply declare i separately in each .cpp file:
namespace {
int i;
}
Putting it in an anonymous namespace as above keeps it from being accessible from other .cpp files, for safety.
Sorry if this question seems trivial to many here.
In a C++ code there is something as below:
class Foo
{
public:
static int bands;
...
...
private:
...
...
}//class definition ends
int Foo::bands; //Note: here its not initialized to any value!
Why is the above statement needed again when 'bands' is once declared inside the class as static?
Also can a static variable be declared as a private member variable in any class?
C++ notes a distinction between declaring and defining. bands is declared within the class, but not defined.
A non-static data member would be defined when you define an object of that type, but since a static member is not a part of any one specific object, it needs it's own definition.
a) It's needed because that's the way the languge is designed.
b) Static variables are initialized by their default constructor, or to zero for built-in types.
c) Yes, they can be (and usually are) private.
Take a look at this question.
It has to do with obj files, how they are used, and how memory addresses for globally scoped variables are ultimately discovered through the linking process. Object files contain the addresses of all global data and functions defined in the corresponding cpp. They layout some memory in a relative fashion to tell the liker where in that file these global vars/funcs can be found. So for example
function doFoo can be found 0 bytes from beginning of this file
int foo::bands can be found 12 bytes from beginning of this file
etc
Its almost easier to think about if you've done straight C before. In a pure C world you would do things in a more traditional modular programming sense. Your module would be defined with a header and a cpp. The header would define a "public" variable like below, using the extern keyword, then instantiate it in the cpp.
foo.h
extern int bands;
foo.cpp
#include "foo.h"
int bands;
foo.obj:
int bands can be found 0 bytes from the beginning of this file
The "extern" keyword states that this name is valid and its address will get resolved at link time. Everyone that included "foo.h" and wanted to use the "bands" global variable had could now use it. At link time, the linker would figure out that bands existed in the foo.obj. If you forgot to put "int bands" in foo.obj, you'd get a linker error, and have to go resolve it.
In C++ using static in a class declaration i similar. You are telling the users that there exists this thing called "foo::bands" and where it will live will get resolved at link time. Later down the line, the linker sees that in foo.obj, foo::bands exists, and all references to foo::bands can be resolved.
My understanding is that you would only need to declare Foo::bands if you planned on using it prior to ever creating an instance of your class. Basically, when you declare a static in a C++ class then only one copy of that variable exists for all instances of that class. However, you can't normally access Foo::bands until an instance of the class is declared.
For example:
Pointers to Members
#include <iostream>
using namespace std;
class X {
public:
int a;
void f(int b) {
cout << "The value of b is "<< b << endl;
}
};
int main() {
// declare pointer to data member
int X::*ptiptr = &X::a;
// declare a pointer to member function
void (X::* ptfptr) (int) = &X::f;
// create an object of class type X
X xobject;
// initialize data member
xobject.*ptiptr = 10;
cout << "The value of a is " << xobject.*ptiptr << endl;
// call member function
(xobject.*ptfptr) (20);
}