Well, I'm learning C++ and never really learned how to do stuff that is not OO.
I'm trying to get a bit more experience coding in C style.
GobalInformation.h
#pragma once
#ifndef GLOBALINFORMATION_H
#define GLOBALINFORMATION_H
#include "MapInformation.h"
namespace gi {
MapInformation mapInf;
};
#endif
I would like to be able to access gi::mapInf from every header and cpp in my project. Right now I'm including globalinformation.h in every header, so I'm getting linker errors with multiple definitions.
How can I work around the problem?
In header file only do
namespace gi {
extern MapInformation mapInf;
};
In CPP file provide the actual definition.
namespace gi {
MapInformation mapInf;
};
It will work as you intend.
If you are using the MapInformation across dynamic link library boundaries you might have to link against the library that includes the definition cpp file. Also on Window you might have to use dllimport/dllexport
Be aware that having globals in multiple compilation units can easily lead to order-of-initialization problems. You may wish to consider replacing each global with a function that returns a reference. In your case, put this in one cpp file and declare it in the header:
namespace gi {
MapInformation& getMapInf()
{
static MapInformation result;
return result;
}
}
Global variables are C, but namespaces are C++. There is a good discussion on using global variables and how they can be replaced by Singleton pattern: Globals and Singletons
And here is a simple sample: CPP/Classes/Singleton
Perhaps a better solution is to create a global object that contains all your global data. Then pass a smart pointer to the classes that actually need to access this shared global data.
Example:
class GlobalData
{
public:
int ticks_;
};
//Other file
class ThatNeedsGlobalData
{
public:
ThatNeedsGlobalData(std::shared_ptr<GlobalData> globalData);
};
This will save you some trouble.
Good luck!
Here are a few things that you need to take care of while trying to use global variables the way you have used.
Ensure that all the header files that the header files that GobalInformation.h includes are also enclosed insides #ifndefs. (I could not see mapinformation.h so I assume you have done it)
Just like CPP, C compiler also does not ensure order of the initialization of variables in different translation units(different C/CPP files).
Hence declare the header file as
//GlobalInformation.h
namespace gi {
extern MapInformation mapInf;
};
In a function that you know would be called first initialize the variable. This way lazy-initialization can also be acheived in C.
Related
Throughout a C++ codebase I'm working in, the pattern for declaring constants looks something like this.
// module_constants.h
#ifndef MODULE_CONSTANTS
#define MODULE_CONSTANTS
namespace module {
extern const int SOME_CONST;
}
#endif
// module_constants.cpp
#include "module_constants.h"
namespace module {
const int SOME_CONST = 1;
}
What are the merits of this approach rather than defining all of the constant values in the header?
The single advantage I know of is that you only have to recompile a single cpp-file when you change the constant’s value and not every file that directly or indirectly includes the header file.
That can be particularly useful when you provide a dynamically linked library and want to patch it without recompiling the actual application.
Some drawbacks are that
(as latedeveloper wrote) you can't use them at places where a constant expression is required (e.g. array bounds or template parameters) outside of the cppfile, in which you defined it.
you make the optimizer's life harder.
from a tooling perspective e.g. intellisense won't show you it's value.
Well, by putting it in the header you'd run into the one-definition rule if you include it in more than one cpp file.
But, on the other hand, you can create it as a constexpr in the header I believe.
I have a project in code blocks that uses many different files - quite often written by other programmers. At the moment I have a situation in which I have two different sub-projects containing function named in the same manner. Let's say: F(int x). So F(int x) is defined in two source files in two different locations and they have two different headers. Also I have created two different namespaces for those headers:
namespace NS1
{
extern "C"{
#include "header1definingF.h"
}
}
namespace NS2
{
extern "C"{
#include "header2definingF.h"
}
}
But still compiler complains that it has multiple definition of F(int x). How can I workaround this in Code::Blocks (In Visual Studio it works just fine).
EDIT: To be more clear those headers include C code. I haven't thought it will be so messy. There are like thousands of source files using other projects including thousands of functions again... so what to do. I have absolutely no idea how to make it work.
I wonder why it works on Visual Studio, but not on Code Blocks. This suggests you do have an include guard.
Does this help?
Project->Build options...->Linker settings (tab)
-Wl,--allow-multiple-definition
I can't understand your problems clearly, but i think you should understand how the compiler works, when you use gcc to compel your program, your program first will be run include operator, that means if you include a header, the compiler will copy the header file to the file. if you include the header twice there will be a twice define error.so you must guarantee once,you can use
#ifndef __FILE_NAME__
#define __FILE_NAME__
// your code
#endif
If your problem is the redefine the function, you should know how the compiler distinguish the function, i think your problem is you do not use the namespace when you use the function.
The problem is that the namespace do not work for C functions (extern "C").
Here is a simple sample which do not compile:
namespace NS1
{
extern "C"{
int f()
{
return 1;
}
}
}
namespace NS2
{
extern "C"{
int f()
{
return 2;
}
}
}
In this case the two functions are different but have the same name: f(). If you just declare the functions, it will compile but they must refer to the same function.
This second sample works fine. The functions have the name NS1::f() and NS2::f() which are differents.
namespace NS1
{
int f()
{
return 1;
}
}
namespace NS2
{
int f()
{
return 2;
}
}
If you want to use two different c code, you can use objcopy which can help you to have a NS1_f() and NS2_f() function. After that you should rename all functions of the libraries in your includes. In this case, no namespace are used. This is normal, there is no namespace in C. Equivalent functions:
int NS1_f()
{
return 1;
}
int NS2_f()
{
return 2;
}
Short of editing the .cpp files themselves and renaming the functions (which is not a practical solution), your options are either making sure to only include one of the header files with duplicate functions at a time (which could be a huge maintainance problem) or, and this would be my recommendation, make use of namespaces. They will save you a ton of hassle in this situation.
You may need one of two things. The following is called a Header Guard:
#ifndef MYHEADER_H
#define MYHEADER_H
//your header code goes here
#endif
This way the header is only included once per object file that asks for it. However, if you want to have two methods with the same identifier, they have to be part of different Namespaces:
namespace myspace1{
void func(void);
};
namespace myspace2{
void func(void);
};
Other than that, there's not really much else you can do. You shouldn't have two functions with the same name in general. Also, you would have to modify this in the header files that you mentioned.
You are allowed to declare functions as often as you want, however they can only have ONE definition.
I believe you have to edit cpp files as well to nest the two functions into a corresponding namespace. Plus, you have to choose which function you want to call like namespace::function() or you can use using namespace with either of the namespaces you created. Hope this helps!
[Updates #1] It is easier to get confused between the declaration and definition of a function. Remember that you can redeclare non-member functions. Thus, if a header file only contains non-member function declarations, it is safe to include it multiple times in one translation unit (a cpp file). Adding ifndef/define in a header file is a good habit for avoiding potential problems but that is not what resolves your problem.
Your problem is that you want to have two different function definitions with the same function signature(its name and arguments) and that's not allowed in C++. You can either change one of their signatures or put them into a different namespace (which you are trying but without touching their definitions). Both ways require you to edit files containing their definitions.
[Updates #2]
As you updated the question with that the code is in C, I've searched and found this:
What should I do if two libraries provide a function with the same name generating a conflict?
it will surely help you to understand your problem more clearly and find a solution. Good luck!
So I am trying to make a C++ / OpenGL program (using Visual Studio 2010) that deals with Keyboard Input using a class called Operation. The point is to learn a few things since I'm new to both C++ and OpenGL.
I'm using an array 'bool keysDown[256]' to store which keys are pressed. Likewise I want to make an array of operations 'Operation *keyOps[256]', to operate those keys.
And here comes my problem, most of those keys will have no operation so I want an Operation class that will do absolutely nothing, but I only need one global instance/pointer that different files can use.
Now what I wanted to do, was to somehow create a single instance of this 'no operation' class and make it usable in any files that include this header without needing to declare it in each file. (Something like NULL, only in the shape of an Operation class)
So far my 'solution' was to use a namespace like this,
(operation.h)
#ifndef _OPERATION_H
#define _OPERATION_H
#include <iostream>
#include <GL\glut.h>
namespace operations{
class Operation{
protected:
std::string _name;
public:
Operation(std::string name) : _name(name){}
virtual void operate()=0;
std::string getName(){return _name;}
};
(...)
class OPnop: public Operation{
public:
OPnop(): Operation("No operation"){}
void operate(){}
};
static OPnop OPNOP;
Operation* nop(); //implemented in .cpp > {return &OPNOP;}
(...)
};
#endif
Other files can get a pointer to the OPNOP instance by using the operations::nop() function. I've tested and it works, but I'm not sure this works as intended in the background.
I have been searching for extern and static usage on global variables, but I probably didn't understand it all and I didn't find an answer I could relate to my problem. If I'm not mistaken extern variables have to be declared in other files too while static creates a different variable for each file including it.
So my question is, is there a way to declare/instantiate this 'no operation' so that all the files including this header will have access to the same unique instance directly without having to use a function?
Indeed the static keyword has a different meaning in the namespace context than the class context. I believe what you want to do is declare it as extern in your header, and in the implementation (.cpp) file initialize it once. Take a look at this question.
I did something similar here.
I'm using a Gesture class with a single global instance as gGesture to handle all the user interactions.
// .h file
struct Gesture_{
int fingers;
int taps;
eGestureAction action;
bool continious;
};
typedef struct Gesture_ Gesture;
extern Gesture gGesture;
To answer your question on static vs extern, the extern avoids linker problems by not adding same symbol to all translation units.
Notes:
The code was originally intended to work in a C based project, but I think you'll get the idea.
The Gesture object is intended for Touch based devices.
I am writing a utility library which is made up of several "Packages". The classes in each package are contained in various namespaces. I have an idea as to how I can simplify the situation by automatically declaring using statements at the end of class declarations (see below), this will avoid having the programmer do it in a cpp file.
namespace Utility
{
class String
{
// Class Implementation
};
}
using Utility::String;
My understanding is that if the user includes the header String.h and String is in Utility then the programmer will want to use String. Obviously this could be bad if there are outside classes chain including a bunch of files which dirty up the namespace so I thought how about making it a #define instead.
namespace Utility
{
class String
{
// Class Implementation
};
}
#ifdef AUTO_DECLARE_NAMESPACE
using Utility::String;
#endif
That way, programmers that want this extended functionality can get it.
Would this a good idea or is there something I'm overlooking?
There is no point in using namespaces if you are just going to add a using declaration for each and every name declared in the namespace.
Let users of your header files decide how they want to use the headers. If someone wants to use a using declaration, let him do it in the .cpp file directly; this will make the code in that .cpp file clearer since it will be apparent where the name originated.
This seems at best pointless, and at worst annoying.
What is wrong with having developers decide which namespaces to use and what to qualify fully?
Honestly, I believe that's what the using namespace directive is for. There's no need for you to add this preprocessor mechanism, considering the using namespace directive does just that.
Couldn't you have another .h file with all your usings like my_lib_import_names.h and just #include that to get what you want?
You would probably have problem with classes not being declared but you could probably bypass it by using something like:
#ifdef UTILITY_STRING_H_
using Utility::String;
#endif
..
#ifdef UTILITY_SOMETHING_ELSE_H
using Utility::SomethingElse;
#endif
..
What do you think?
That way you could retain the "expected" behavior in your library .h but also have your the way you like. You also get to keep the benefit of the namespace over your classes (at the expense of having to maintain your new .h file).
I have a C++ code that's a physics simulation tool.
I would like to store some physical constants, conversion factor between different sets of units, and also some more application specific constants (such as definition like enum Planes {X=0, Y=1}) and I would like to be able to access them from everywhere in my code.
What would be the best way to do that ?
I think one way would be to create a namespace namespace constants (which can then be a nested namespace in my main namespace) with nested namespaces (like 'constants', 'units', etc.).
Would it be the way you would do that ?
If I use that method, do I have to make it a header file and include it everywhere ?
If I understand correctly the variables in the namespace at global scope have static linkage, but no external linkage. Then if I want to use them without including a file, I also have to declare them extern ?
As you can see I am a bit confused about that...
Namespace constants are the way to go in most cases.
If I use that method, do I have to make it a header file and include it everywhere ?
Yes, or not everywhere but only where it's really USED.
If I understand correctly the variables in the namespace at global scope have static linkage, but no external linkage. Then if I want to use them without including a file, I also have to declare them extern ?
Yes, you have to do it that way :
// header
namespace modulename
{
// maybe add another namespace to specify that you have constants, but taste-dependant
namespace domain // like maths or physics
{
extern const Number THIS_NUMBER; // have to be defined in the cpp
extern const int THAT_NUMBER = 256; // if it's int-based type, you can define it -here - BUT DON'T IF IT CAN BE CHANGED : all files including this one would have to be recompiled at each value change!!
}
}
// .cpp, where you have the definitions
namespace modulename
{
namespace domain // like maths or physics
{
const Number THIS_NUMBER = Number( 256.42f ); // definition - static is implicit
}
}
If the compiler doesn't say anything about it being unrecognized then you are safe. All that matters is that the compiler knows where to find the variable. Once you include the header file, it is technically a copy and paste of the code in that file. Given this, you need to do some precompiler directives.
#ifndef _MYGLOBALS
#define _MYGLOBALS
int global_integer;
long global_long;
#endif
This ensures that they will only be included once, and you will not have many references of the variables in your code.
I'd make a constants namespace and put in all globally-relevant constants there. Any constants only relevant to a single class, declare as static consts within the class itself.