How does one avoid accidentally redeclaring global constants in C++? - c++

I have a template matrix class class defined in a header called "Matrix.h".
Certain matrices are used repeatedly in my program. I thought that I would define these in the "Matrix.h" header file, like so:
const Matrix<GLfloat> B_SPLINE_TO_BEZIER_MATRIX(4, 4, values);
When I do this g++ complains that I redefined the constant in question. This happens because I include Matrix.h in two different source files. When the object files for these are compiled, both end up with a definition of the matrix above, causing the error message.
My question is how do I avoid this situation? I want a constant that is accessible to more than one file, but I don't know where to put it.

You avoid it by:
Declaring it extern in the header. A symbol can be declared any number of times.
Defining it in the implementation, only once.

If you don't want to split it between a header and implementation file,
Declare your constant static (or declare it in anonymous namespace) to make definition private. Linker will not complain, but it will result in multiple private copies across compilation units.
static Matrix<GLfloat> B_SPLINE_TO_BEZIER_MATRIX(4, 4, values);
Make an inline function that returns the constant. Inline function definitions produce "weak" symbols in object file, so linker will eliminate duplicates and pick one.
inline const Matrix<GLfloat>&
GET_B_SPLINE_TO_BEZIER_MATRIX() {
const static Matrix<GLfloat> B_SPLINE_TO_BEZIER_MATRIX(4, 4, values);
return B_SPLINE_TO_BEZIER_MATRIX;
}

just write your header file like this
#ifndef HEADER_FILE_NAME_H
#define HEADER_FILE_NAME_H
// your header file code
#endif
this will make sure that it won't get declared multiple times

Wrap header files (.h) in preprocessor conditionals to prevent them from being included in the compiler's symbol table twice:
#ifndef HEADER_NAME
#define HEADER_NAME
// code...
#endif//HEADER_NAME
HEADER_NAME can really be anything, but it's best to make sure that it's something related to the file to prevent more collisions, as this is just defining an empty preprocessor macro (which also ends up in the symbol table).

Related

Understanding C linker error: multiple definition

I have a project with multiple header files and .cpp files.
All of the header files have include guards.
There is a file called Constants.h where I define some constants. Some of these with defines, some as constant variables.
There are more header-.cpp-file pairs with code in them. One of these does contain a class, the others don't.
When I include my files into my main file (an arduino sketch), I get a lot of linker errors, claiming there are multiple definitions of some variables.
I read that this mainly occurs when you include .c or .cpp files, which I don't do. All the .cpp files only include their appropriate header files.
I did manage to find multiple solution proposals:
1) inline:
With functions, inline can be used to get rid of this problem. However, this is not possible with variables.
2) anonymous namespace:
This is one of the solutions I used. I put anonymous namespaces around all the problematic definitions I had. It did work, however I do not understand why this works. Could anyone help me understand it?
3) moving definitions into .cpp files:
This is another approach I used sometimes, but it wasn't always possible since I needed some of my definitions in other code, not belonging to this header file or its code (which I do admit is bad design).
Could anyone explain to me where exactly the problem lies and why these approaches work?
Some of these with defines, some as constant variables.
In C const does not imply the same thing as it does in C++. If you have this:
const int foo = 3;
In a header, then any C++ translation unit that includes the header will have a static variable named foo (the const at namespace scope implies internal linkage). Moreover, foo can even be considered a constant expression by many C++ constructs.
Such is not the case in C. There foo is an object at file scope with external linkage. So you will have multiple definitions from C translation units.
A quick fix would be to alter the definitions into something like this:
static const int foo = 3;
This is redundant in C++ but required in C.
In addition to Story Teller's excellent explanation, to define global variables, use the following:
// module.h
#include "glo.h"
// glo.h
#ifndef EXTERN
# define EXTERN extern
#endif
EXTERN int myvar;
// main.c
#define EXTERN
#include "glo.h"
In main.c all variables will be declared (i.e. space is allocated for them), in all other c files that include glo.h, all variables will be known.
You shouldn't declare any object in header files, this should be moved to c\c++ files.
In header you may:
declare types such as: classes, structs, typedefs etc.
put forward declarations of (not classes) functions
put inline (or in classes) functions (+ body)
you may add extern declaration.
you may put your macros.
a static declaration may declare things multiple times, therefore it is not recommended.

gcc Multiple definition...release only

I have defined a function within a header file. In debug, it compiles and links fine. In release, I get the compile error "multiple definition of `blah::blah(blah& blah)'" for every object file of every class that includes the header.
I'm using gcc-4.8.1. I can't post up the actual code, this version has names changed to protect the innocent:
#ifndef INCLUDE_SMELLS_FUNNY
#define INCLUDE_SMELLS_FUNNY
#include "ParentClass.h"
#include "ChildClassA.h"
#include "ChildClassB.h"
namespace someplace {
bool smellsFunny(const ParentClass& someData) {
// All ChildClass As smell funny
if(dynamic_cast<const ChildClassA*>(&someData)) {
return true;
}
// If ChildClass B, need to check if smells funny
const ChildClassB* childB = dynamic_cast<const ChildClassB*>(&someData)
if(childB) {
return childB->MoreThanAWeekOld();
}
// Default is smells OK
return false;
}
}
#endif // INCLUDE_SMELLS_FUNNY
I haven't been able to find which gcc flag is responsible.
Of course, a fix is just to move the implementation into a cpp file. But why is this necessary? Why does this happen only in release?
It's because you define the function in a header file, and then include that header file in multiple source files. That means the function will be defined in each source file (technically, translation unit) where you include the header.
There are a couple of solutions to this:
Mark the function as static. That means that each definition in the translation units will not be exported.
Mark the function as inline. This works basically the same as the first alternative.
Put the definition of the function in a source file, and only have its declaration in the header file.
For a small function like the one you have, then alternative 2 might be a good one. If you have a larger function, that can't easily be inlined, you should go with alternative 3.
Also, if you go with number 3, then you don't need to include the header files, and then lessen the risk of circular inclusion.
Since you have placed the function definition in the header, you need to mark it inline:
inline bool smellsFunny(const ParentClass& someData) { ...
This is because every place in which you include the header will have a definition of the function, breaking the one definition rule (ODR). inline lets you work around the ODR.
As to why there is no problem in release mode, that doesn't make sense: the code is not correct. It could be that release mode is declaring the function inline for you.
I can not say exactly but maybe in the debug mode the function is considered as inline function.
If the function is in a header file, you need to declare it inline, unless it's defined within a class.

Adding more code makes code uncompileable

I have a header file which begins with
#if !defined(__GLOBAL_H)
#define __GLOBAL_H
then some code followed by
#endif
The code contains only function declarations, some include of other header files and the a few template functions. However, the problem occurs when I add one single line of code. I get linker error that the function I added has already been defined in an object file. I'm using Visual Studio 2012 Premium as compiler. I have tried to remove any existing function from the header file, and that also goes through the compiler. On the other hand, if I add any new line that may be new to the compiler, it refuses to compile saying it has already been defined. Does anyone have any clue what might be wrong or can I have stumbled upon an error inside the compiler itself? (which I highly doubt)
Edit:
The solution was to declare the function the the header file, but to define it in the CPP file. But the real issue was that when I include a header file for returning an object of the type declared in the header file, it does not compile. It many of the errors "Missing ; in front of *" which was types declared in other header files.
Although you haven't shown use any code or error messages, I'm guessing that there are function definitions (including the code for the function body), not just declarations, in the header.
These must either be declared inline, which allows them to be defined in more than one translation unit; or moved into a single source file, leaving just the declaration in the header, so they are only defined on one translation unit.
The "One Definition Rule" says that (unless they are inline) functions may only have one definition in the program.
Also, your include guard shouldn't begin with an underscore, nor contain a double underscore; names like that are reserved.
Adding non-inlined function definitions to header files is generally bad. The compiler will generate code for the function in every file it is included in resulting in the redefintion error you are encountering. Instead you should declare the function in the header and place the definition in a source file (.cpp).
Global.h
#if !defined(__GLOBAL_H)
#define __GLOBAL_H
void somefunction(); // <-- declaring the function.
#endif
SomeSource.cpp
#include "Global.h"
// Here is where define the function
void somefunction()
{
}

C++ include guard doesn't appear to work?

I have used include guards many times before, but never really understood how or why they work.
Why doesn't the following work?
#ifndef CAMERA_CLASS_HPP
#define CAMERA_CLASS_HPP
class camera_class
{
....
};
camera_class glcam = camera_class();
#endif // CAMERA_CLASS_HPP
The error is this: (You can probably guess what it's going to be from the title of this question!)
-------------- Build: Debug in System ---------------
Linking console executable: bin/Debug/System
/usr/bin/ld: error: obj/Debug/main.o: multiple definition of 'glcam'
/usr/bin/ld: obj/Debug/camera_class.o: previous definition here
/usr/bin/ld: error: obj/Debug/main.glfunc.o: multiple definition of 'glcam'
/usr/bin/ld: obj/Debug/camera_class.o: previous definition here
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 0 seconds)
0 errors, 0 warnings
Also, could someone please explain to me why a header guard works?
The header guard will prevent multiple inclusions in a single translation unit. The header can (and is) being included in multiple translation units:
// a.cpp:
#include "camera.hpp"
// b.cpp
#include "camera.hpp"
This will produce a a.obj and a b.obj, each containing a definition for glcam. When linked together to produce the final binary you get the multiple definition error.
You need to declare glcam in the header and define it exactly once in a .cpp file:
// camera.hpp
...
extern camera_class glcam;
// camera.cpp
#include "camera.hpp"
camera_class glcam;
Root Cause:
The header guard prevents inclusion of the same header multiple times in the same translation unit but not across different translation units. When you include the same header file in multiple translation units then,
A copy of glcam is indeed being created in every translation unit where you include the header.
C++ standard mandates that each symbol can be defined only once(One Definition Rule) and hence the linker issues you the error.
Solution:
Do not create glcam in the header file. Instead it should be created in such a way that it gets defined only once. The correct way to do this is by using the keyword extern.
It looks like you want to create a single glcam object that can be used in multiple places. I would do that by exposing a free function to return a static instance. This is similar to using extern, but I find it to be a little more explicit in its intent.
#ifndef CAMERA_CLASS_HPP
#define CAMERA_CLASS_HPP
class camera_class
{
....
};
camera_class& get_camera();
#endif // CAMERA_CLASS_HPP
// in the CPP
camera_class& get_camera()
{
static camera_class the_camera;
return the_camera;
}
This gives you the ability to use a single camera_class instance without relying on extern, but at the same time doesn't force you to use it as a singleton, as other areas of the code are free to create their own private instances as well.
This could be implemented as it is (a free-function) or as a static member function of the camera_class. I chose the former, based on some excellent advice from Scott Meyers:
If you're writing a function that can be implemented as either a
member or as a non-friend non-member, you should prefer to implement
it as a non-member function.
Source: http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197
Since you are including this file from several files, you are breaking the One Definition Rule:
In the entire program, an object or non-inline function cannot have
more than one definition
You should put the glcam definition in a source file, rather than in a header file, or instead declare it as extern, and provide a definition in some source file.
The include guard prevents multiple instances of the text in your header from appearing in one compilation unit (ie a single .cpp you're building which gets built into a .o)
It doesn't prevent multiple instances of that text from appearing in multiple compilation units.
So at link time, each compilation unit that includes this header has a
camera_class glcam = camera_class();
As a symbol. C++ can't decide when referring to "glcam" which single global definition you mean. The one from main.o or the one from camera_class.o?
It's working just fine, you're only getting one definition in each of your source files.
The problem is that you have multiple source files and the linker is finding multiple definitions.
In the header file you should put:
extern camera_class glcam;
And then in one and only one source file put what you used to have in the header:
camera_class glcam = camera_class();
At this point you'll need to be aware of initialization order problems. Don't try to use glcam from any static objects.

function defintion in header file in C++

I have C++ project which consists of multiple (in fact many) .cpp and .h files. While writing header files i have a file as follows
For eg MyHeaderFile.h
#ifndef _MYHEARDERFILE_H
#define _MYHEARDERFILE_H
// Here i have function defintion.
void myFunc() {cout << "my function" << endl; }
#endif
Above file is included in multiple files. While compiling i have getting "multiple definition of "myfunc" error.
I am expecting the header is included only once as i have #ifndef check so i am expecting error should not be thrown.
For example in case of templates we have to define in header file, in this case how we can avoid the problem i am facing now?
Can any one please help me why i am seeing the error? is my understanding right?
Thanks!
Normally, one puts function declarations in header files, and function definitions (i.e. the actual function body/implementation) in source files. Otherwise, you get exactly the issue you're seeing: the header file is #included (i.e. substituted) into multiple source files, so the function ends up being defined multiple times. This confuses the linker, so it complains.
The header-guard #ifndef ... stuff only prevents a header from being substituted into the same source file multiple times. Remember that each source file is compiled completely independently from all the others; all #defines and other definitions are "reset" for each one.
One possible alternative solution is to leave the function definition in the header file, but simply to mark it inline (this has the side-effect of eliminating the linker error). But, personally, I wouldn't do that.
Every function must be defined only once in a single translation unit (this is called One definition rule, and applies not only to functions). By placing the definition in a header which is then included, you are violating this rule.
You can simply leave the declaration
void myFunc();
in the header, and define myFunc in a .cpp which provides the definition.
Otherwise you can declare your function inline.
Note that when using templates, instead, you are usually led (for template-related specific issues) to place definitions directly in the headers, which could appear surprising given the problems you are facing now.