views:

1356

answers:

4

Hi, I'm getting the LNK2005: already defined in (...) error when building my project in Visual Studio 2008. I've referenced other related questions, but mine seems to be a bit more complicated due if nothing else to the number of files I'm working with.

First, I think it will be helpful for me to map out the #include statements I have in the files of my project in the format [current_file] ->includes_this_file

All my header files are guarded with the standard #ifndef [Header] #define [Header] ... #endif.

[Modulator.h]

prototypes for Modulator class

[ChorusUnit.h] ->Modulator.h

prototypes for Chorus classes which have member objects of type Modulator

[AudioHandler.h] ->ChorusUnit.h

prototypes for AudioHandler class which has member objects of Chorus classes

[Chorus.cpp] ->AudioHandler.h

definitions for the members of Modulator and Chorus classes

[AudioHandler.cpp] ->Chorus.cpp

definitions for the members of AudioHandler class

[ChorusUnit.cpp] ->AudioHandler.cpp

the file containing the main() function that actually runs the code of my project.

The ordering of includes is because all the definitions of functions to the classes found in Modulator.h, ChorusUnit.h, and AudioHandler.h need to reference members of the other classes, so I needed the prototypes defined first for all the classes to see each other.

The error specifically says that every single definition found in Chorus.cpp and AudioHandler.cpp in file Chorus.obj is already defined in AudioHandler.obj. Also there is another set of the same error type that says every single definition found in Chorus.cpp and AudioHandler.cpp in file ChorusUnit.obj is already defined in AudioHandler.obj.

There is probably a pretty straightforward solution, but I am not particularly experience (being mostly a Java programmer) in linking in general. As far as my limited knowledge on the subject goes, I only defined everything once and everything was only included once so I'm personally at a loss as to why these are already defined. Some please enlighten me!

+3  A: 

[AudioHandler.cpp] ->Chorus.cpp

definitions for the members of AudioHandler class

This is wrong. Include ChorusUnit.hpp for prototypes.

dirkgently
So I should rename Chorus.cpp to Chorus.hpp? I don't already have a file of this name in my project.
Rich
That'd be ChorusUnit.h -- whatever file that contains prototypes for the functions defined in Chorus.cpp
dirkgently
Oh, okay. I think I understand. When I'm including the header files I don't need to also reference the definitions in the .cpp file because the compiler/linker will do that on its own since I included the header?
Rich
Exactly. Now, do we have a fix for your problem?
dirkgently
+7  A: 

The error is probably that you say you #include Chorus.cpp in AudioHandle.cpp - this is not what you probably want.

The reason is, that all .cpp files (unless you've done something special in your IDE) are compiled separately, then linked. When you #include another .cpp file, the file's text is literally included; therefore, all objects defined in the included file appear in the including file as well. When you link the two files, the common objects cause a conflict.

jpalecek
+2  A: 

AudioHandler.cpp and ChorusUnit.cpp should only #include header files, not other C++ source files.

The preprocessor inserts the contents of any #included file into the #including file, so you get two copies of the symbols from Chorus.cpp once you start linking: one from compiling Chorus.cpp and the second from compiling AudioHandler.cpp (since it #includes Chorus.cpp).

rkb
A: 

I'm not sure how to do this on Windows machines, but these problems can generally be solved by running the code through the C Preprocessor ONLY. This will result in a combined source file essentially replacing all "#include" statements with the files they refer to. If you view this combined file, it can become obvious where things are being redefined. In Linux/Unix, you would do this using the 'cpp' command.

Ryan Van Antwerp