views:

4815

answers:

8

I can't seem to get rid of these seemingly random compiles errors in one of my classes. I get about 4 errors such as:

multiple definition of `draw_line(float, float, float, float)'
and
multiple definition of `near_far_clip(float, float, float*, float*, float*, float*, float*, float*)'

that are flagged in the middle of the method.

I also consistently get "multiple definition of `stack'" in the middle another method. stack is a global variable in a totally different file. It isn't even mentioned in the file I'm getting the error in.

I tried separating the error prone file into .h and .cpp files (was originally just a .cpp) and nothing about the error changed...

I don't have duplicated methods. I only have one #include of lines.h and there is an ifndef clause at the beginning. All these errors appear in the .cpp file.

Any ideas what it could be?

Alright I got the code up:

http://code.bulix.org/wrmmiw-70109 ---------lines.cpp
http://code.bulix.org/l2milw-70110 ---------ThreeD.cpp
http://code.bulix.org/e50rga-70111 ----------ThreeD.h
http://code.bulix.org/3ctuqy-70112 ----------makefile

The lines.cpp is a converted .c file I received from my instructor. I included the makefile just in case, because I always have problems with it. I also annotated exactly where the errors were flagged in the file, but they seem pretty random so I don't know if it's particularly important. I abandoned the .h file because it wasn't solving anything or helping. I believe it will be easier to find the mistake without it.

Here is also the requested main.cpp file (there is no .h)

http://code.bulix.org/9img79-70113


I remade the lines.h file due to and I'm still receiving the:

multiple definition of draw_line(float, float, float, float)' and multiple definition of near_far_clip(float, float, float*, float*, float*, float*, float*, float*)'

errors in the lines.cpp file, but the "multiple definition of `stack'" error is now in a random place in the ThreeD.cpp file (and is marked by a comment now) ^This error has been fixed and the files have been revised to show this

Updated files: http://code.bulix.org/pl0ha3-70114 -------------lines.h

http://code.bulix.org/en2iiq-70124 -------------lines.cpp

http://code.bulix.org/ec1l4c-70125 -------------ThreeD.cpp

http://code.bulix.org/cm691a-70117 ------------ThreeD.h

I appreciate the help greatly. I messed around with labeling some the global variables extern, but it didn't seem to affect anything.

+3  A: 

Please post some code snippets. Maybe you are defining your methods in both the class declaration and outside?

class X {
    void foo();    // No definition, just declaration
    void bar() {}  // Declaration + definition
};

void X::foo() {}    // First Definition, OK
void X::bar() {}    // Already defined, ERROR
Ferdinand Beyer
+1  A: 

Multiple definition errors are linker errors, but without more information it's difficult to diagnose them. Check the same file does not appear twice in the linker command and that your header files contain only declarations, no definitions.

anon
+1  A: 

Without seeing the code there's really no helping you. The compiler clearly claims the opposite of you (there is at least one duplicate definition).

Try reproducing the error with a minimum example. Have you tried compiling the code outside Eclipse in the command line? With what result?

Konrad Rudolph
A good answer, @KR, but I see no mention of Eclipse in the question.
paxdiablo
@Pax, It was in the original question. I edited it out because it didn't seem too important to the question (the only mention of Eclipse was in the title).
strager
Ah. I must remember to check history before I open my trap :-)
paxdiablo
+8  A: 

You are likely including the function definitions in a header file. Include the inline keyword so they are not exported by each object file, or put them in their own .cpp file.

For your global variable, you need to use the extern keyword in your header file. Otherwise, each object file exports their own variable and the linker gets confused as to which is the correct one to use.

strager
+3  A: 

Check include guards on misspelling.
Check your make options, maybe someone compiled into multiple object files.
Try to exclude parts of files and code until not find cause of errors.

EDITED:
fix include *.cpp files. They are should be linked.

bb
What exactly do you mean? Are you talking about the makefile or one of the .h/.cpp files?
Chad
You have #include "lines.cpp" in ThreeD.cpp - this same as all code from lines.cpp was copy-pasted in ThreeD.cpp - with funcion definition. Also lines.cpp - separeted compiled entity with same functions. It cause linker error.
bb
create lines.h, insert declaration of those functions in lines, and include this lines.h
bb
I believe I did what you said, but I'm still getting the same errors. I updated the code
Chad
One other problem! You have global variable stack in both ThreeD.cpp and main.cpp. Define this variables as static.
bb
Fixed. Thanks. But the original errors regarding the multiple definitions of those functions are still there :-/
Chad
update please source file with places of multiple definition.
bb
Both ThreeD.cpp and lines.cpp have been updated
Chad
and makefile please..
bb
makefile hasn't changed
Chad
oops. it seems i have not idea. please do clean and build. if error happens provide line for which error will displayed and full text of error.
bb
what status? it works after clean-rebuild?
bb
+2  A: 

As has been said - not enough information to properly diagnose here.

But if draw_line et al are defined in a header file rather than in a source (cpp) file, you may have methods which are supposedly declared as inline in the header file, which aren't actually properly inlining. In that case, each .cpp file that includes the header will generate their own definition of the draw_line function, and generate warnings at link time.

This can happen if you use a #defined INLINE macro which comes from a system header that has been forgotten or removed, and for whatever reason the INLINE gets pre-processed away into nothing.

E.g.:

//Lines.h

#define GCCC //Note the typo

#if defined(GCC)
#define INLINE inline
#elif defined (MSVC)
#define INLINE __inline
#else

#define INLINE //Due to the typo, INLINE will be turned into nothing
#endif

INLINE void draw_line(float x1, float y1, float x2, float y2)
{
   //Draw the line
}

//File1.cpp
#include "lines.h" //will define draw_line

//File2.cpp
#include "lines.h" //will also define draw_line

And linking File1.cpp and File2.cpp will generate multiple declaration errors

MrCranky
+2  A: 

Why do you #include lines.cpp in ThreeD.cpp? This is very unusual.

Your makefile wants lines.o, so you're going to compile lines.cpp. Anything defined in lines.cpp will be in lines.o and also in ThreeD.o.

There is an intriguing comment in lines.cpp:

Don't forget to put declarations in your .h files.

I think the instructor wants you to break lines.cpp into a .h and a .cpp.

Excerpt from lines.cpp:

/* These go in your .h file or in lines.h */
/*

Line drawing header.

*/


void draw_line(float, float, float, float);
int near_far_clip(float, float, float *, float *, float *, float *,
                  float *, float *);

I suspect that these two declarations are the only thing that should be in lines.h.

Thomas L Holaday
So I could use the methods of lines.cppI had it in ThreeD.h, but I was moving it around to see if there was any difference. I get the a few more errors when it is in the .h file, but they're all of the same type. Should this matter?
Chad
Yes, it will matter. Break the lines.cpp into an .h file and a .cpp file, then #include only lines.h in ThreeD.cpp.
Thomas L Holaday
I did that beforehand. I received exactly the same errors, so I returned it to its original state. Is there any changes I should make to the makefile (regarding your comment on lines.cpp being defined in lines.o and ThreeD.o?)
Chad
You can take lines.o out of the makefile, but it is a kludge. The correct thing to do is to break lines.cpp into a lines.h and lines.cpp, where lines.h has only declarations of the functions you are using in ThreeD.
Thomas L Holaday
I tried to follow these instructions and updated the pastebins. Still the same error.
Chad
The lines.h I see in the paste bins does not have draw_line and near_far_clip.
Thomas L Holaday
Delete your .o files so you get a clean build, using exactly the sources in the paste bins, and post your errors.
Thomas L Holaday
Holy shit it compiled. I deleted all the .o files and tried to build again and one of the other .cpp files was full or errors. I changed the methods to static instead of extern (so I could keep the scope) and I recompiled and it built. Thanks a million.
Chad
You're welcome. Now get out there and draw us some awesome boxes!
Thomas L Holaday
A: 

Hi, What I see here that the basic rule applies for ll. I will explain how the things work in these kind of errors and wht those comes : Let's take one example of "Making a global variable"

Dont confuse the header file, for a cpp file. The header is only there to allow multiple file projects to have a common interface before linking.

1.List item

You should give info about the global variable in header:

extern int Var_Global;

  1. List item

    while keeping the Actual code in the
    cpp :
    
    
    int Var_Global;
    

And make sure you 1. include the header, and 2. link the code.

Link the code once, and once only, and there is only one copy of the data, howver you can include headers all day long, this tells the other code that there will be a copy of the data at link time.

I see a lot of people putting code in header files, while that may work in some cases, it is a bad habit to get into, and will cause problems sooner or later.

Regards,

Prashanta