After learning more about classes and pointers, I refactored a program I had and wiped out > 200 lines of code, in the process creating two other classes, Location and Piece. The problem is, after getting everything to compile, the linker complains that the constructor for Piece is defined multiple times, with a load of errors:
In function 'Piece': board.o
multiple definition of 'Piece::Piece(int)` char_traits.h
In function 'Piece': board.o
multiple definition of 'Piece::Piece(int)` piece.cpp
In function 'Piece': player.o
multiple definition of 'Piece::Piece(int)` piece.cpp
In function 'Piece': player.o
multiple definition of 'Piece::Piece(int)` piece.cpp (yes, same exact error!)
In function 'Piece': refereee.o
multiple definition of 'Piece::Piece(int)` char_traits.h
In function 'Piece': referee.o
multiple definition of 'Piece::Piece(int)` piece.cpp
...
When I click on the error for char_traits.h, it brings me to this:
static size_t
length(const char_type* __s) //error points here to line 262
{ return __builtin_strlen(__s); }
Another char_traits.h brings me to
static int
compare(const char_type* __s1, const char_type* __s2, size_t __n) //line 258, error points here too
{ return __builtin_memcmp(__s1, __s2, __n); }
And just so you know, location.h is the only thing that includes piece.h (well, other files include piece.h indirectly from location including piece.h), board.h is the only thing that includes location.h, and a bunch of classes include board.h
I tried changing the header guard to _OTHELLO_PIECE_H, and tried renaming the class to OPiece (via the IDE). Neither fixed the problem.
The funny thing is, one of the errors has an "in function 'OPiece':", and after that my IDE puts chatter.o, even though neither chatter.h nor chatter.cpp includes anything that includes OPiece.
Any idea what might be causing this redefinition error?
Rebuild everything
Look for Piece::Piece, and remove all such from header files
2b. Never #include .cpp files
Look for #define that resolves to Piece
The most common cause of a multiple function definition error is putting a function definition in a header file and forgetting to make it inline.
I wouldn't worry much about char_traits.h - this probably means that because of some template runaround, the linker couldn't figure out a better place to claim the definition happened in that particular object file.
You should put the implementation of the constructor in piece.cpp, not directly in piece.h.
there are two places to implement Piece::Piece(int) in a typical build:
1) the interface (at declaration)
class Piece {
int d_a;
public:
Piece(int a) : d_a(a) {
}
/* ... */
};
2) in a dedicated cpp file
in Piece.hpp
class Piece {
int d_a;
public:
Piece(int a);
/* ... */
};
in Piece.cpp
Piece::Piece(int a) : d_a(a) {
}
however, templates are defined differently.
the error often indicates that Piece::Piece(int a) : d_a(a) {} is included in multiple cpp files.
each object file produced adds the symbol Piece::Piece(int) where it is visible.
at the end of the build, all objects are merged/linked to create your final binary or executable. then the linker sees that there are copies of this definition and produces an error.
one quick way to diagnose this is (assuming your builds do not take long):
#warning Piece::Piece(int) is visible here
Piece::Piece(int a) : d_a(a) {
}
exactly one warning should be emitted. if more are emitted, then the compiler will likely provide a bit of information (such as the include order).
Just a guess: Did you use #include or did you use #import by accident -- which happened to me once :-)
Related
I just feel weird about how does that work ?
That my first time that I've ever seen that , two c++ files located in the same directory "Test1.cpp,Test2.cpp"
Test1.cpp :
#include <iostream>
void magic();
int main(){
magic();
return 0;
}
Test2.cpp :
#include <iostream>
using namespace std;
void magic(){
cout << "That's not a magic , it's a logical thing.." << endl;
}
As I mentioned above , they are in the same directory , with prototype of 'magic' function.
Now my question is , how does magic work without any inclusion of Test2.cpp ?
Does C++ include it by default ? if that's true , then why do we need to include our classes ? why do we need header file while cpp file can does its purpose ?
In order to obtain an executable from a C++ source code two main phases are required:
compilation phase;
linking phase.
The first one searches only for the signature of the functions and check if the function call is compatible with the found declarations.
The second one searches the implementation of the function among the libraries or objects linked through the options specified through command line of the linker (some compilers can automatically run the linker adding some command line options).
So you need to understand the compiler and linker options in order to understand this process.
The main catch of headers file is simplifying writing of code.
Let's think about next example:
test2.cpp
#include <iostream>
using namespace std;
void my ()
{ magic(); } // here we don't know what magic() is and compiler will complain
void magic(){
cout << "That's not a magic , it's a logical thing.." << endl;
}
This code gives next error:
gaal#linux-t420:~/Downloads> g++ test2.cpp
test2.cpp: In function ‘void my()’:
test2.cpp:6:9: error: ‘magic’ was not declared in this scope
{ magic(); } // here we don't know what magic() is and compiler will complain
^
To avoid this error we need to place declaration of magic() function before definition of my(). So it is good idea to place ALL declarations in one place. Header file is a such place. If we don't use headers, we'll need to paste declaration of magic() function in any cpp-file where it will be used.
I have a conceptual doubt which i'll try to put across using an example:
main.cpp
#include "array_list.cpp"
int main()
{
array_list list1;
return 0;
}
Scenario1:
array_list.cpp->
class array_list
{
private:
int list[10];
public:
array_list () {};
~array_list () {};
void set_element (int,int);
};
void array_list::set_element (int i,int a) {
list[i] = a;
}
Error:
main.obj : error LNK2005: "public: void __thiscall array_list::set_element(int,int)" (?set_element#array_list##QAEXHH#Z) already defined in array_list.obj
1>C:\Users\vrastog\Documents\Visual Studio 2012\Projects\C++ learning\Debug\list using arrays.exe : fatal error LNK1169: one or more multiply defined symbols found
Scenario 2:
array_list.cpp->
class array_list
{
private:
int list[10];
public:
array_list () {};
~array_list () {};
void set_element (int i,int a) {
list[i] = a;
}
};
Error: No error!!
Question: I understand the reason for error. The same method has been defined twice, once in main.obj and second in array_list.obj and hence, it should be an error.
My question is why does the second scenario work? Here also, since we have includes array_list.cpp in the main file, 'set_element' should have been defined twice here as well. What am I missing here?
Please don't include .cpp files.
In the first example, the function is defined out of class, you need to add inline, otherwise it's a multiple definition.
In the second example, the function is defined in the class definition, so it's an implicit inline function (it's like the compiler added the inline for you), that's why it's not causing multiple definitions.
In-class definition makes a method inline, and therefore it does not cause a multiple definition error in the object file.
An inline method should be implemented in every translation unit it is used in, so the inline method compiles into both object files.
C++ Standard Draft (n3797) 3.2.4: An inline function shall be defined in every translation unit in which it is odr-used.
Also 3.2.6 requires that these function should be exactly the same.
g++ implements this using weak symbols: inline functions are special exported functions that do not cause multiple definition error when linking.
Use a tool like nm under Linux and see for yourself. It emits a weak symbol into the object file:
$ nm arraylist.o
00000000 W _ZN10array_list11set_elementEii
(... ctors, dtors ...)
00000000 T main
Also, if you do not use the function, or the compiler inlines all occurrences, it may get optimized out.
I have a question concerning inlining methods.
I am using a library developed for collision models. One header file responsible for graphic interface contains declaration and implementation of the functions but the functions are not inlined. Therefore, it is impossible to include those functions in several translation units.
As an illustration here is a dummy code I designed for illustration :
LivingBeing.h
#ifndef LIVINGBEING_H
#define LIVINGBEING_H
class LivingBeing
{
public:
LivingBeing(double _size);
void breathe();
private:
double size;
};
//////////////
LivingBeing::LivingBeing(double _size)
{
size = _size;
}
void LivingBeing::breathe()
{
// do something
}
#endif
Forest.h
#ifndef FOREST_H
#define FOREST_H
#include "LivingBeing.h"
class Forest
{
public:
Forest(int _numberLivingBeings);
private:
int numberLivingBeings;
};
#endif
Forest.cpp
#include "Forest.h"
Forest::Forest(int _numberLivingBeings)
{
numberLivingBeings = _numberLivingBeings;
// Call LivingBeing constructor, methods etc...
}
Main.cpp
#include "Forest.h"
int main()
{
Forest forest = Forest(10);
return 0;
}
This code does not compile unless I add the inline keyword in front of the constructor LivingBeing and the method breathe. The error message is :
1>main_test.obj : error LNK2005: "public: __thiscall LivingBeing::LivingBeing(double)" (??0LivingBeing##QAE#N#Z) already defined in Forest.obj
1>main_test.obj : error LNK2005: "public: void __thiscall LivingBeing::breathe(void)" (?breathe#LivingBeing##QAEXXZ) already defined in Forest.obj
1>C:\Users\******\Documents\Visual Studio 2010\Projects\TutorialChronoEngine\Debug\Test_3.exe : fatal error LNK1169: one or more multiply defined symbols found
My question is : what is the drawbacks of inlining methods ? The real library I am using is pretty large, I would like to inline methods from a specific file (in my example it would be LivingBeing.h) so that it is possible to use those methods in several .cpp files. What am I risking by changing the source file as such ?
Thanks a lot
You are defining functions (LivingBeing::LivingBeing and LivingBeing::breathe) in a header, which means there will be a definition in each translation unit that includes that header. This breaks the One Definition Rule (ODR), hence the link error.
You have three options:
Move the function definitions into a source file so they are only defined once; or
Declare them inline to allow multiple identical definitions; or
Move the definitions inside the class definition, which implicitly makes them inline.
what is the drawbacks of inlining methods ?
Possibly increased compilation time and executable size; but you'd need to measure to see whether there's any noticable difference.
A less stable API - client code will need recompiling whenever any inline function changes.
The possibility of accidentally breaking the ODR, for example if a function contains macros which might have different expansions in different translation units.
Just because a method is defined in a "source" file (.c/.cpp) doesn't mean it won't be inlined... link-time operations may perform that optimization. Oppositely, just because a method is declared and implemented as inline in a header file doesn't mean it will be inlined. In general, I define methods in a header file if they are very simple, e.g. int getWidth() const { return width; }, or MyObj* getNext() { return internal_itor ? internal_itor->next : 0; }
I'm a novice programmer, still in the midst of trying to learn C++ and OOP design basics. The project that I've been working on to teach myself is a C++ game that has multiple classes, files, states, etc. However, I keep running into snags with file organization that range from simply struggling with where to create objects to compile-breaking linker errors.
Here's an example of some of the errors that I've been getting:
1>SMGA.obj : error LNK2005: "class Engine smgaEngine" (?smgaEngine##3VEngine##A) already defined in Engine.obj
1>SplashScreenState.obj : error LNK2005: "class Engine smgaEngine" (?smgaEngine##3VEngine##A) already defined in Engine.obj
1>StateManager.obj : error LNK2005: "class StateManager gameStateManager" (?gameStateManager##3VStateManager##A) already defined in Engine.obj
1>MSVCRTD.lib(cinitexe.obj) : warning LNK4098: defaultlib 'msvcrt.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
I've looked around online and I've seen a lot of ~similar~ problems that involve bad include guards or the inclusion of .cpp files instead of .h files. But I haven't done that in my code, so I'm at a loss.
Now, I'm guessing that the error is telling me that I'm trying to create the smgaEngine object of the Engine class (and the gameStateManager object of the StateManager class) twice, but I'm not sure why...
The thing that stands out about these two objects (smgaEngine and gameStateManager) is that I declared them in their corresponding class' .h files immediately after the class declaration. Could this be the issue? - They're still within the include guards, and I wasn't too sure about where else to put them in my code... Would this sloppy coding be the cause of linker errors?
Here's one of the suspect classes...
#ifndef ENGINE_H
#define ENGINE_H
#include <SDL.h>
#include "Timer.h"
class Engine
{
private:
static const int screenWidth = 480;
static const int screenHeight = 270;
static const int screenBPP = 24;
bool running;
SDL_Surface *mainScreen;
SDL_Event eventHolder;
Timer fpsTimer;
public:
Engine();
~Engine();
void init();
void handleEvents();
void handleLogic();
void handleRender();
void cleanUp();
SDL_Event *getEvent();
SDL_Surface *getMainScreen();
bool isRunning();
void setRunning(bool tempRunning);
} smgaEngine;
#endif
And here's the other one:
#ifndef STATEMANAGER_H
#define STATEMANAGER_H
#include "SplashScreenState.h"
#include <vector>
class GameState;
class StateManager
{
private:
std::vector<GameState*> stateStack;
SplashScreenState *splashState;
public:
StateManager();
~StateManager();
void init();
void changeState( GameState *tempNextState );
void addState( GameState *tempNextState );
void removeState();
//returns the back() element of the stateStack vector..
GameState* getTopState();
void handleEvents();
void handleLogic();
void handleRender();
} gameStateManager;
#endif
I've been trying my best to learn C++ and OOP, but I've really been struggling. It seems that every time I attempt to make clean code with encapsulated classes, I end up with a confusing mess. I'm trying to prevent a high degree of class coupling, but I often end up with either linker errors or a lack of ability to communicate between classes... Is it creation of class instance objects within the header files that is causing these errors or is it something else? And if that is the cause of my linker errors, then where should I be creating these objects?
You have defined two global variables, smgaEngine and gameStateManager in your header files, and you have included those header files in two (or more) source files. So you get multiple definition errors. Include guards don't stop header files being included twice in different source files (how could they?) they stop header files being included twice in the same source file.
You're quite close to the correct answer (at least you have a good understanding of the problem). The right way is this
// header file Engine.h
class Engine
{
};
extern Engine smgaEngine;
// in one source file (say Engine.cpp)
Engine smgaEngine;
What you have now is a declaration in the header file (extern makes it a declaration), but a definition in the source file. You can have as many declarations as you like (as long as they are consistent) but you must have only one definition. So for global variables put declarations in the header file and put a definition in one of the source files.
consider a fun.cpp file :
class fun
{
public:
void sum();
void dispaly();
};
Class fun2
{
public:
void subtract();
};
Now consider another c++ file execute.cpp where i want to access only subtract method of fun.cpp file..
i dont want to include "fun.cpp" file into my execute.cpp as it will increase the size(in larger projects)..
so, how can i access any particular method wihtod including the file????
i dont want to include "fun.cpp" file into my execute.cpp
Nor should you, as it would break the one definition rule (assuming the implementations are also in the cpp file).
The usual way to do this is to have the class definition in a header, and include only the header file.
To answer your question, you can, but it's fugly.
C++ allows us to define a class multiple times, as long as the definition is identical. So, in execute.cpp you can simply write:
//execute.cpp
class fun2 //note lower-case 'c'
{
public:
void subtract();
};
// use fun2 here
before you use it. But, again, the usual way is to break the class definition and implementation in a .h file and a .cpp file.
Mandatory advice: read a good introductory C++ book.
You need to include the header file which defines the class fun(and has the declaration of subtract()) in the cpp file where you want to use the function subtract().
Note that the function must be defined though.
fun2.h
#ifndef FUN2_H
#define FUN2_H
Class fun2
{
public:
void subtract();
};
#endif // FUN2_H
fun2.cpp
#include "fun2.h"
void func2::subtract()
{
}
execute.cpp
#include "fun2.h"
//use subtract() through object of `fun2`
Note that, to use a member function in a particular source file, the definition of the class which declares that function should be visible to the compiler, the actual job of linking to the particular definition is done at the linking stage and as long as you follow the above format the linker shall link the appropriate function for you.
Even though you include the file, the linker will only include code that is actually used. This is why using static libraries is sometimes preferable to a dynamic library that has to include everything.
You can't. You need to actually include the file that links to the code that defines the function if you want to include the function. If you just need the interface and aren't going to use the function, you could simply declare the class in execute.cpp as follows
class fun
{
public:
void subtract();
};
But you couldn't use subtract there.