Confused about Multiple Definitions in C++ Programs

Started by
15 comments, last by Anthony Serrano 16 years, 8 months ago
I've been searching around google about this one option I use when compiling my program with g++, "-z muldefs". I understand that this means I'm declaring things multiple times in my program. But I'm kinda confused about how to fix my program from these multiple definitions? Sorta how my program is: - A few .cpp files, but tons of .h files with the classes defined inline. - Lots of global variables accessed from throughout the program. - Quite a few places where there are circular references between classes (so I use preemptive class declarations). I know some of these are bad programming practice, and I'm looking to correct them. But I've always been a little confused about the whole "export" statement and such between source files.
Advertisement
post source.
I would but it's around 10K lines and there isn't any particular file that's causing the problem (problem has metastasized you could say).

In any case, here is the makefile:

# NOTES:# -g is for Compiling with Debug information for g++# -z muldefs is required to allow for multiple definitions# -o automates the compile-link process########################### PLGRNSE MAIN ENGINE ############################ FOR DEBUGGING#PLGRNSEmake: ./Source/main.cpp ./Source/Cell.cpp  POPSPLITTERmake  LATTICEGENmake#	g++ -g ./Source/main.cpp ./Source/Cell.cpp -z muldefs -o ./Build/PLGRNSE_BUILD 	# OPTIMIZEDPLGRNSEmake: ./Source/main.cpp ./Source/Cell.cpp POPSPLITTERmake  LATTICEGENmake	g++ -O3 ./Source/main.cpp ./Source/Cell.cpp -z muldefs -o ./Build/PLGRNSE_BUILD  ########################### POPULATION SPLITTER ############################ FOR DEBUGGINGPOPSPLITTERmake: ./Source/PopulationSplitter.cpp	g++ -g ./Source/PopulationSplitter.cpp -z muldefs -o ./Build/POPSPLITTER	# OPTIMIZED#POPSPLITTERmake: ./Source/PopulationSplitter.cpp#	g++ -O3 ./Source/PopulationSplitter.cpp -z muldefs -o ./Build/POPSPLITTER###########################  LATTICE GENERATOR  ############################ FOR DEBUGGINGLATTICEGENmake: ./Source/LatticeGenerator.cpp	g++ -g ./Source/LatticeGenerator.cpp -z muldefs -o ./Build/LATTICE_GENERATOR	# OPTIMIZED#LATTICEGENmake: ./Source/LatticeGenerator.cpp#	g++ -O3 ./Source/LatticeGenerator.cpp -z muldefs -o ./Build/LATTICE_GENERATOR


and Eclipse gives me the following error:

make PLGRNSEmake
g++ -g ./Source/PopulationSplitter.cpp -z muldefs -o ./Build/POPSPLITTER
g++.exe: muldefs: No such file or directory

but this is on Windows. When I'm doing this in Ubuntu, there is no such error. I think it's because MinGW/Cygwin's support for GCC is not as extensive?
The obligatory Organizing Code Files in C and C++.


jfl.
Thanks, I read through that article and will try out that stuff. (I was suffering from problems 3 and 4).
Ok I did all of that, but now one question I have is about enumerations. I have three files:

globals.cpp: declares enum SPECIES{blah blah blah}
globals.h: extern enum SPECIES;
main.cpp: tries to use constants in SPECIES.

But main.cpp is not recognizing enum SPECIES even though I have included globals.h.

G++ says that I cannot apply extern to an enumeration. How then can I make this enumeration globally visible?
Quote:Original post by Sagar_Indurkhya
How then can I make this enumeration globally visible?


Declare it in header.
Quote:Original post by Sagar_Indurkhya
Ok I did all of that, but now one question I have is about enumerations. I have three files:

globals.cpp: declares enum SPECIES{blah blah blah}
globals.h: extern enum SPECIES;
main.cpp: tries to use constants in SPECIES.

But main.cpp is not recognizing enum SPECIES even though I have included globals.h.

G++ says that I cannot apply extern to an enumeration. How then can I make this enumeration globally visible?


Enums define data types, not storage, so it is legit to put them in the header, just like function prototypes and class bodies.
Ah I thought about that. But see, the program is designed around other people modifying one specific source file (globals.cpp) and only that file if I can help it. The enumeration defined in globals.cpp is very important specifically for that purpose, which is why initially all that stuff was in globals.h, and then I had to use -z muldefs. Is there no way to make it visible from the source file instead of declaring it in the header file?
Quote:Original post by Sagar_Indurkhya
Ah I thought about that. But see, the program is designed around other people modifying one specific source file (globals.cpp) and only that file if I can help it. The enumeration defined in globals.cpp is very important specifically for that purpose, which is why initially all that stuff was in globals.h, and then I had to use -z muldefs. Is there no way to make it visible from the source file instead of declaring it in the header file?


sup Sagar, I'm Carl and I was in your multi-var class at NCSSM.

but why would you want to declare the enum in the source file if you want it to be globally visible? an enum is a data type and therefore should technically be in a header.

have you tried using header guards? they can help you out with multiple definitions.

example:
#ifndef HEADER_FILE_NAME_H#define HEADER_FILE_NAME_H// code#endif // HEADER_FILE_NAME_H



the end result is that if a header has already been included, it won't be included a second time.

also, I think it's good to avoid using things like global variables left over from the days of C, and instead use proper object-oriented programming practices to achieve the same effect.

This topic is closed to new replies.

Advertisement