multiple definition error c++ - c++

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

Related

How to create a Union the complicated way?

So I stumbled upon this when playing around with compilation units.
I have 2 headers that define a class with the same name. The first compilation unit includes the first header and declares an extern pointer to the class, the second compilation unit includes the second header and defines the pointer.
Now I have T* pointing to an U.
mcve:
h1.h
#pragma once
struct a_struct {
int i;
a_struct(int _i) : i{ _i } {}
};
h2.h
#pragma once
struct a_struct {
float f;
a_struct(float _f) : f{ _f } {}
};
foo.h
#pragma once
struct foo {
int bar();
};
cu1.cpp
#include "foo.h"
#include "h1.h"
extern a_struct* s;
int foo::bar() {
return s->i;
}
cu2.cpp
#include "h2.h"
a_struct* s = new a_struct(1.0f);
main.cpp
#include "foo.h"
#include <iostream>
int main() {
foo f;
std::cout << f.bar() << std::endl; // <- 1065353216
system("PAUSE");
return 0;
}
Why doesn't the linker see that h1.h::a_struct is not a h2.h::a_struct ? Is this mentioned in the standard as undefined behaviour ?
(Also I know naming 2 classes with the same name is stupid...)
Is this mentioned in the standard as undefined behaviour ?
Yes, this is a violation of the "header version" of the One Definition Rule. In this version, which applies to class definitions, inline functions and variables, and other such things commonly defined in header files, multiple definitions of a single entity are allowed in separate translation units, but those definitions must all have the same tokens (after preprocessing) and must all mean essentially the same thing. Multiple definitions which aren't the same in this way are undefined behavior. See [basic.def.odr]/12 in the C++20 draft, and the fifth paragraph under One Definition Rule at cppreference.com.
Why doesn't the linker see that h1.h ::a_struct is not a h2.h ::a_struct ?
In most C++ implementations, the compiler converts a translation unit into an object file containing function code and symbol definitions, and the function code may make use of additional "undefined symbols" to be defined by other objects. By the point of an object file, little is saved about C++ source or type information, except possibly in debugger data. A linker will probably see just that function foo::bar() in cu1.o uses the undefined symbol s, cu2.o defines the symbol s, and the global-dynamic-initialization function of cu2.o also uses the symbol s. The linker will just adjust things so that executing foo::bar() will correctly access the same object s, without much caring what any function actually does with the bytes belonging to that symbol.
(Linkers can sometimes warn when object files disagree about the number of bytes associated with a symbol, but two pointers-to-class-type objects will probably have the same size.)
The compiler compiles each source files separately. It trusts a given class declaration to be the same for all source files.
When you do as above, you trick the compiler into compiling two files with two different definition for some class. Each file generates a self-consistent piece of code.
Then the linker comes in and links your various bits of code together. There's an object/library format which is shared across all compilers. This is to allow every linker to work with every compiler. At this point, all the linker knows is that some code will pass a foo object and some other code will receive a foo object. It's not its business to go peek and check and complain.
Keep in mind that, at link-time, the source code might not even be available. You may have a library from some vendor without source code. And there might be various #defines that could have affected this object. The linker doesn't need to know what the compilation settings were, or even what the source was. The code could even have been written in another language.
To gain this flexibility and interoperability, there's some rules you have to follow. One of them is "don't define the same class twice in different ways".

When a method is defined inside class scope, project won't compile unless method is invoked somewhere else in the original cpp file

Here's the body of main.cpp
#include "Header.h"
int main()
{
auto f = Foo();
f.bar();
return 0;
}
Here's the body of Header.h
class Foo {
public:
void bar();
};
Here's the body of Source.cpp
#include <iostream>
class Foo {
public:
void bar() {
std::cout << "Foo.bar() called\n";
}
};
void t() {
auto f = Foo();
f.bar(); // If this line isn't here, the project won't compile
}
When I comment out f.bar(); in Source.cpp, I receive the following error upon compilation. It's telling me that f.bar() in main() is unresolved:
Error LNK2019 unresolved external symbol "public: void __thiscall
Foo::bar(void)" (?bar#Foo##QAEXXZ) referenced in function _main ...
I understand that it's common to define methods outside of class scope, and indeed the following version of Source.cpp compiles successfully--
#include <iostream>
#include "Header.h"
void Foo::bar() {
std::cout << "Foo.bar() called\n";
}
Nonetheless, I don't understand what's wrong with the original version. It feels like something mysterious and magical is going on that I don't fully understand.
This is an ODR violation either way, because the class Foo as defined in the header, and the class Foo as defined in the cpp file are not token by token identical.
out of line definition of bar should look like
#include <iostream>
#include "Header.h"
void Foo::bar() {
std::cout << "Foo.bar() called\n";
}
Note that ODR violations are 'no diagnostics required'
(this is why one of the examples compiles, the compiler can't always detect ODR violations)
The best way to not accidentally create errors like this is to always include the header-file in the file/files where you implement the methods.
When we are talking about good practices, don't forget the include-guard in the header-file.
If a method is short enough to be inline defined, (style may vary, but for me that means a short oneliner), then that inline definition need to be present in the header-file, so that the compiler sees an identical type every time it encounters it.
Your original program violates the One Definition Rule (ODR), defined in C++14, 3.2. The relevant paragraph is number 6:
There can be more than one definition of a class type [...] in a program
provided that each definition appears in a different translation unit,
and provided the definitions satisfy the following requirements. Given such
an entity name D defined in more than one translation unit, then
each definition of D shall consist of the same sequence of tokens; and
[...]
You have two translation units: main.cpp with all its header files (including Header.h), and Source.cpp with all its header files (which do not include Header.h). Both translation units contain a definition of the class ::Foo: main.cpp contains the one from Header.h, and Source.cpp has its own.
However, the two do not consist of the same sequence of tokens. The one in Source.cpp contains an inline function definition.
The reason for having one definition of a class in a header and only getting it by including this header is two-fold:
You save the effort of duplicating it, and more importantly, finding every duplicate if you have to change it.
Barring preprocessor shenanigans, with there being only one textual form of the definition, you cannot run afoul of the ODR.
Note that ODR violations are "no diagnostic required" - in your case you get an error, but as you saw, the error disappears if you call the function in Source.cpp. That doesn't mean your program became correct; it just means that the compiler was no longer capable of discovering the error; nonetheless, very strange behavior could occur. Your program has undefined behavior.
Take a look at the C++ standard 9.3.2 (n4296):
" ... A member function may be defined (8.4) in its class definition, in which case it is an inline member function
(7.1.2), or it may be defined outside of its class definition if it has already been declared but not defined
in its class definition. A member function definition that appears outside of the class definition shall appear
in a namespace scope enclosing the class definition. Except for member function definitions that appear
outside of a class definition, and except for explicit specializations of member functions of class templates
and member function templates (14.7) appearing outside of the class definition, a member function shall not
be redeclared ..."
& 9.3.3 :
" ...An inline member function (whether static or non-static) may also be defined outside of its class definition
provided either its declaration in the class definition or its definition outside of the class definition declares
the function as inline.[ Note: Member functions of a class in namespace scope have the linkage of that
class. Member functions of a local class (9.8) have no linkage. See 3.5. —end note ] ..."
Since bar() is defined inside Foo { }; it is implicitly inline.
I believe taking the above clauses into consideration together implies that Foo::bar has local linkage in Source.cpp & is not visible to anyone else. What I find confusing is that calling f.bar() changes the linkage allowing your other example to compile.
Compiler take the cpp files one by one, there's no way the compiler will remember what else he compiled in another file
main.cpp - include header. Header contains a class declaration. main.obj expects that foo() will be implemented as a separate symbol available at linking time. Done, write the object file and forget
Source.cpp redeclare the class without including the header. As such, the compiler cannot complain of the double declaration. As in the Source.cpp declaration the foo method is implemented inline, the compiler (not knowing anything about what main expects) does not generate a linkage symbol for the method, Done, write the object and forget
linker loads both objects, see that the 'main.obj' needs a linkage symbol for the foo method, searches everywhere and cannot find one - because the Source.obj does not contain one - the compiler was instructed the method will be inline.
Makes sense?

Why should I not initialize static variable in header? [duplicate]

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

How do C++ find the function declaration

I need help translating a concept from Java to C++.
In Java, when you create a class and give it methods (functions), you must define the function in that class so that it can be properly called by any class instance that might want to.
For example, in the class Employee you'd declare and define the method salaryRaise(int amount).
Whenever an Employee object wants to use it, it calls Employee.salaryRaise(i) and Java knows exactly where to find it - in the Employee class.
In C++, functions are declared in .h files and then defined somewhere else.
How does the compiler know where to find this method?
That is really the job of the linker, not the compiler. The compiler will call the function referencing a symbol that is yet undefined. The linker will then get the different translation units and resolve the symbols by name (that is, the mangled names that encodes additional information as the namespaces, types of the arguments...)
You declare the function in the header (.h) file. That header file then gets #includeed in any other files where you need to use the function. This satisfies the compiler, because it knows the signature of the function and how to call it.
The function is then defined in the source (.cpp) file. The source file includes it's own header file, so that when you compile it, you end up with an object file containing the complete compiled code for that function.
The linker then links any parts of your code where you've called the function (i.e. the files where you included the header), with the actual code for that function.
EDIT with example:
Foo.h:
#ifndef FOO_H
#define FOO_H
class Foo
{
public:
int fooFunction(double a);
};
#endif
Foo.cpp:
#include "Foo.h"
int Foo::fooFunction(double a)
{
// Function definition
return 1;
}
Compiling Foo.cpp generates Foo.obj which contains the complete definition for fooFunction. So far so good.
Bar.h:
#ifndef BAR_H
#define BAR_H
#include "Foo.h"
class Bar
{
public:
void barFunction();
};
#endif
Bar.cpp:
#include "Bar.h"
void Bar::barFunction()
{
Foo foo;
int returnValue = foo.fooFunction(2.0);
}
Bar.cpp includes Bar.h which in turn includes Foo.h. When Bar.cpp gets preprocessed therefore, the declarations for Foo::fooFunction are inserted at the top of the file. So, when the statement int returnValue = foo.fooFunction(2.0); is compiled, the compiler knows how to emit the machine instructions to call fooFunction because it knows the type of the return value (int) and it knows the types of the parameters (a double, and an implicit this pointer for the foo object). Because no function definition was provided, the function will not be inlined (inlining means the entire code for the function is copied into the point at which it is called). Instead, a pointer to the memory address of the function is used to call it. Because a pointer is being used, the compiler doesn't care about the definition - all it needs to know is "I need to call a function X at memory location Y with parameters A and B, and I need to have an int sized memory section ready to store the return value, and I'll assume that the code at that address knows how to perform the function". However, the compiler has no way to know what the address of that function will be in advance (because the function definition lives in a separate .cpp file and will be part of a separate compilation job AKA translation unit).
That's where the linker comes in. Once all the translation units have been compiled (which could be in any arbitrary order), the linker goes back to the compiled code for Bar.cpp and links the two together by filling in the address for the now compiled definition of fooFunction at the point at which it is called in Bar.cpp, thus making the compiled code fully executable.
In C++, functions are declared in .h files and then defined somewhere else. How does the compiler know where to find this method?
Because you tell it where to find it when you provide the definition of the method.
Consider a hypothetical header file:
class Gizmo
{
public:
bool Foo();
};
Now we will define the Foo method above in another CPP file:
bool Gizmo::Foo()
{
return true;
}
Here's the paraphrased dialogue you have with the above definition:
Ok, compiler. I'm defining a function which returns a bool. The
function is part of the class Gizmo, and the function is named Foo.
The function takes no parameters. The definition of the function is:
return true.
The scope resolution token :: separates a name of an enclosing class and the name of the function.
If you had left that Gizmo:: bit out, and instead wrote:
bool Foo()
{
return true;
}
The you would still be defining a function named Foo which takes no parameters and returns a bool, but now instead of defining it to be part of Gizmo, you are defining it to be on it's own. A so-called "free function" or "global function." This would compile just fine, but you would get an "unresolved external" linker error if some other code somewhere was trying to use Gizmo::Foo().
When the compiler transforms your source to binary, it usually builds intermediary files (aka object files) that contain (among other things) the member functions of a class.
At the time of linking the intermediary files are translated into machine code. If all member functions used can be resolved at that time, all is good, otherwise you get a linking error.
This way, you can place the definition of member functions anywhere in the project -- as long as the linker finds what it needs, it can build the binary. It is not advised, however as this approach will make reading/understanding the class purpose/mechanic harder for humans
A compiler will typically have a compilation stage and a linking stage. The compilation stage compiles source files into object files. The linking stage will collect the object files and create an executable image. During the linking stage, symbols that were left unresolved in the compilation stage get resolved. This is not much different for either Java and C++. For example, it is how a Java class can call methods on a different Java class.
In C++ you determine the body by class name followed by :: and then method declaration:
class Employee
{
void salaryRaise(int amount); // Now, compiler knows this method belongs to
// the class Employee
};
Then you can define the body:
void Employee::salaryRaise(int amount) // Now, compiler knows everything about
{ ^^^^^^^^^^ // definition of the method
}
For generating object files (and executable binary), you have to pass the .cpp files to the compiler(actually the linker). Therefore everything is visible to the compiler.
In your header file, you prototype/forward declare the class like this.
class Foo
{
private:
int m_Fooint;
int m_Fooint2;
public:
Foo(int a, int b);
int getFooTotal();
};
Then you would define the member functions like this
Foo::Foo(int a, int b) // prototypes names don't have to be the same
{
Foo::m_Fooint = a;
Foo::m_Fooint2 = b;
}
int Foo::getFooTotal()
{
return Foo::m_Fooint + Foo::m_Fooint2;
}
Besides the constructor and destructor, you need to have the data type. Even if it's void and not returning anything.
So you might have something such as
float Foo::getSomeFloat();
or
double Foo::getSomeDouble();
or you can even return an object
OtherClass Foo::getOtherClassObject();

Usage of extern keyword and multiple translation units

I am reading Item 4 of Scott Meyer's Effective C++ where he is trying to show an example where a static non-local object is used across different translation units. He is highlighting the problem whereby the object used in one translation unit does not know if it has been initialised in the other one prior to usage. Its page 30 in the third edition in case anyone has a copy.
The example is such:
One file represents a library:
class FileSystem{
public:
std::size_t numDisks() const;
....
};
extern FileSystem tfs;
and in a client file:
class Directory {
public:
Directory(some_params);
....
};
Directory::Directory(some_params)
{
...
std::size_t disks = tfs.numDisks();
...
}
My two questions are thus:
1) If the client code needs to use tfs, then there will be some sort of include statement. Therefore surely this code is all in one translation unit? I do not see how you could refer to code which is in a different translation unit? Surely a program is always one translation unit?
2) If the client code included FileSystem.h would the line extern FileSystem tfs; be sufficient for the client code to call tfs (I appreciate there could be a run-time issue with initialisation, I am just talking about compile-time scope)?
EDIT to Q1
The book says these two pieces of code are in separate translation units. How could the client code use the variable tfs, knowing they're in separate translation units??
Here's a simplified example of how initialization across multiple TUs can be problematic.
gadget.h:
struct Foo;
extern Foo gadget;
gadget.cpp:
#include <foo.h>
#include <gadget.h>
Foo gadget(true, Blue, 'x'); // initialized here
client.cpp:
#include <foo.h>
#include <gadget.h>
int do_something()
{
int x = gadget.frumple(); // problem!
return bar(x * 2);
}
The problem is that it is not guaranteed that the gadgetobject will have been initialized by the time that do_something() refers to it. It is only guaranteed that initializers within one TU are completed before a function in that TU is called.
(The solution is to replace extern Foo gadget; with Foo & gadget();, implement that in gadget.cpp as { static Foo impl; return impl; } and use gadget().frumple().)
Here's the example from the Standard C++03 (I've added the a.h and b.h headers):
[basic.start.init]/3
// a.h
struct A { A(); Use(){} };
// b.h
struct B { Use(){} };
// – File 1 –
#include "a.h"
#include "b.h"
B b;
A::A(){
b.Use();
}
// – File 2 –
#include "a.h"
A a;
// – File 3 –
#include "a.h"
#include "b.h"
extern A a;
extern B b;
int main() {
a.Use();
b.Use();
}
It is implementation-defined whether either a or b is initialized before main is entered or whether the initializations are delayed until a is first used in main. In particular, if a is initialized before main is entered, it is not guaranteed that b will be initialized before it is used by the initialization of a, that is, before A::A is called. If, however, a is initialized at some point after the first statement of main, b will be initialized prior to its use in A::A.
1) If the client code needs to use tfs, then there will be some sort of include statement. Therefore surely this code is all in one translation unit? I do not see how you could refer to code which is in a different translation unit? Surely a program is always one translation unit?
A translation unit is (roughly) a single .cpp file after preprocessing. After you compile a single translation unit you get a module object (which typically have extension .o or .obj); after all TUs have been compiled, they are linked together by the linker to form the final executable. This is often hid by IDEs (and even by the compilers accepting multiple input files on the command line), but it's crucial to understand that building a C++ program is made in (at least) three passes: precompilation, compilation and linking.
The #include statement will include the declaration of the class and the extern declaration, telling to the current translation unit that the class FileSystem is made that way and that, in some translation unit, there's a variable tfs of type FileSystem.
2) If the client code included FileSystem.h would the line extern FileSystem tfs; be sufficient for the client code to call tfs
Yes, the extern declaration tells the compiler that in some TU there's a variable defined like that; the compiler puts a placeholder for it in the object module and the linker, when tying together the various object modules, will fix it with the address of the actual tfs variable (defined in some other translation unit).
Keep in mind that when you write extern you are only declaring a variable (i.e. you are telling the compiler "trust me, there's this thing somewhere"), when you omit it you are both declaring it and defining it ("there's this thing and you have to create it here").
The distinction maybe is clearer with functions: when you write a prototype you are declaring a function ("somewhere there's a function x that takes such parameters and returns this type"), when you actually write the function (with the function body) you are defining it ("this is what this function actually does"), and, if you haven't declared it before, it counts also as a declaration.
For how multiple TUs are actually used/managed, you can have a look at this answer of mine.