Multiple includes
-
Are you sure you are using the
ClassFromHeaderFile
definitions correctly. IsGetInstance()
a static member with public visibility?It's time for a new signature.
No, what he's getting is an linker error. You either do not link the library which contains the definition, or you're linking in wrong order, or you haven't configured your linker properly. Please, post the makefile (or the command line) you are using to build and link the program.
-
#include <HeaderFileFromLibrary.h>
using namespace NamespaceFromHeaderFile;
int main(int argc, char **args)
{
ClassFromHeaderFile *pClass = ClassFromHeaderFile::GetInstance();. . . return 0;
}
The first row in main throws the following compile error:
undefined reference to `NamespaceFromHeaderFile::ClassFromHeaderFile::GetInstance()'
Cedric Moonen wrote:
Are you sure you linked correctly to the library ?
AAMOF I'm not experienced with C++ coding. As I am an experienced developer in other languages, I can write proper code (Or so I would like to think ;) ), but I don't have the experience for configuring my projects properly. As far as I can tell I did link the library correctly. Any way to make sure of it?
modified on Monday, August 30, 2010 7:40 AM
This is not a COMPILER, but a LINKER ERROR. It has nothing to deal with guards, but to the fact that your main project (not source files, that way it is defined in the IDE environment) doesn't know about the existence of the library project. Since you're using eclipse, you should go to the main project settings and configure it to link also the artifact produced by the library project and configure the projects dependencies so that the library is always built BEFORE the main project. This is one of the most convoluted and confused things that the eclipse CDT has. I've have to admit that -besides a good syntax parser and analyzer- for these relatively trivial things, really sucks!
2 bugs found. > recompile ... 65534 bugs found. :doh:
-
Are you sure you are using the
ClassFromHeaderFile
definitions correctly. IsGetInstance()
a static member with public visibility?It's time for a new signature.
-
No, what he's getting is an linker error. You either do not link the library which contains the definition, or you're linking in wrong order, or you haven't configured your linker properly. Please, post the makefile (or the command line) you are using to build and link the program.
-
Hello experts, I recently solved my duplicate includes problem using the
#ifndef-#define-#endif
pre-processors. However, this somehow causes a problem if classes from the same .h file should be used by different .cpp files. The first .cpp file including the .h file gets compiled, but the others throw an "undefined reference" compile error. It's as if I never included the .h file on the other files. How can I overcome both duplicate includes and single includes problems? A bit on my workstation: OS: Ubuntu. IDE: Eclipse. Compiler: g++ Thanks in advance, Shy.It appears you guys were right. This is a linker issue. Eclipse lets you specify a reference to your other project. Being a devoted Visual Studio for .NET developer, I guess I assumed adding the reference was suffice. However, I've found the specific settings needed for linking the library. For future references to this post: 1. Open the project's settings. 2. Expand "C/C++ Build" and select "Settings". 3. Under "Tool Settings" expand "GCC C++ Linker" and select "Libraries". 4. Add the name of the library on the top box, and the path to its files on the bottom one. (Note that the path to the library should be the project's Debug directory) So now the project gets compiled, and the linker no longer whines about not finding the library. However I get some new linking errors. The new console output is as follows: make all Building target: Maple Invoking: GCC C++ Linker g++ -L"/LibraryPath/Debug" -o"Maple" ./Source/Maple.o -lCursesPlus /LibraryPath/Debug/libCursesPlus.so: undefined reference to `CursesPlus::CursesPlusEngine::initialized' . . . collect2: ld returned 1 exit status make: *** [Maple] Error 1 The vertical three dots hold place for a series of "undefined reference to..." errors, which are similar to the first error, but specify a different member of
CursesPlusEngine
. And to make it clear: Maple is my main executable project, and libCursesPlus is my library project. --Edit-- All of the above members are defined as private static in their corresponding header files.modified on Tuesday, August 31, 2010 4:56 AM
-
paul_71 wrote:
No, what he's getting is an linker error.
His messages are not clear as to whether this is a compiler or linker error. BTW this message should have been in reply to the OP not to me.
It's time for a new signature.
Sorry, these hierarchical"replies" suck!
-
It appears you guys were right. This is a linker issue. Eclipse lets you specify a reference to your other project. Being a devoted Visual Studio for .NET developer, I guess I assumed adding the reference was suffice. However, I've found the specific settings needed for linking the library. For future references to this post: 1. Open the project's settings. 2. Expand "C/C++ Build" and select "Settings". 3. Under "Tool Settings" expand "GCC C++ Linker" and select "Libraries". 4. Add the name of the library on the top box, and the path to its files on the bottom one. (Note that the path to the library should be the project's Debug directory) So now the project gets compiled, and the linker no longer whines about not finding the library. However I get some new linking errors. The new console output is as follows: make all Building target: Maple Invoking: GCC C++ Linker g++ -L"/LibraryPath/Debug" -o"Maple" ./Source/Maple.o -lCursesPlus /LibraryPath/Debug/libCursesPlus.so: undefined reference to `CursesPlus::CursesPlusEngine::initialized' . . . collect2: ld returned 1 exit status make: *** [Maple] Error 1 The vertical three dots hold place for a series of "undefined reference to..." errors, which are similar to the first error, but specify a different member of
CursesPlusEngine
. And to make it clear: Maple is my main executable project, and libCursesPlus is my library project. --Edit-- All of the above members are defined as private static in their corresponding header files.modified on Tuesday, August 31, 2010 4:56 AM
Since you've only got 1 library and 1 runner, and I assume you're not trying to use code from runner in the library, there is only one possibility left: you forgot to add the proper source file(s) to your project(s)...
-
It appears you guys were right. This is a linker issue. Eclipse lets you specify a reference to your other project. Being a devoted Visual Studio for .NET developer, I guess I assumed adding the reference was suffice. However, I've found the specific settings needed for linking the library. For future references to this post: 1. Open the project's settings. 2. Expand "C/C++ Build" and select "Settings". 3. Under "Tool Settings" expand "GCC C++ Linker" and select "Libraries". 4. Add the name of the library on the top box, and the path to its files on the bottom one. (Note that the path to the library should be the project's Debug directory) So now the project gets compiled, and the linker no longer whines about not finding the library. However I get some new linking errors. The new console output is as follows: make all Building target: Maple Invoking: GCC C++ Linker g++ -L"/LibraryPath/Debug" -o"Maple" ./Source/Maple.o -lCursesPlus /LibraryPath/Debug/libCursesPlus.so: undefined reference to `CursesPlus::CursesPlusEngine::initialized' . . . collect2: ld returned 1 exit status make: *** [Maple] Error 1 The vertical three dots hold place for a series of "undefined reference to..." errors, which are similar to the first error, but specify a different member of
CursesPlusEngine
. And to make it clear: Maple is my main executable project, and libCursesPlus is my library project. --Edit-- All of the above members are defined as private static in their corresponding header files.modified on Tuesday, August 31, 2010 4:56 AM
It appears I had to declare the static member variables in both the header files, and the source files. The project now compiles successfully. What's the idea behind this repetitive declaration? It's not like a function which is declared in the header, and defined in the source. It's simply a variable... Oo *Confused*
-
It appears I had to declare the static member variables in both the header files, and the source files. The project now compiles successfully. What's the idea behind this repetitive declaration? It's not like a function which is declared in the header, and defined in the source. It's simply a variable... Oo *Confused*
When you declare a static data member in a class you're telling the compiler: "This class has a static member called ." When you define it outside of a class you're telling the compiler: "You know that variable ? This is where you reserve memory for it and initialise it with ." So it really is identically like a function which is declared in a header and defined in the source. Cheers, Ash PS: It's also identical to the behaviour of global variables - declare in a header, define in source. Which is a big hint why statics are bad, bad, bad...
-
Sorry, these hierarchical"replies" suck!
-
It appears you guys were right. This is a linker issue. Eclipse lets you specify a reference to your other project. Being a devoted Visual Studio for .NET developer, I guess I assumed adding the reference was suffice. However, I've found the specific settings needed for linking the library. For future references to this post: 1. Open the project's settings. 2. Expand "C/C++ Build" and select "Settings". 3. Under "Tool Settings" expand "GCC C++ Linker" and select "Libraries". 4. Add the name of the library on the top box, and the path to its files on the bottom one. (Note that the path to the library should be the project's Debug directory) So now the project gets compiled, and the linker no longer whines about not finding the library. However I get some new linking errors. The new console output is as follows: make all Building target: Maple Invoking: GCC C++ Linker g++ -L"/LibraryPath/Debug" -o"Maple" ./Source/Maple.o -lCursesPlus /LibraryPath/Debug/libCursesPlus.so: undefined reference to `CursesPlus::CursesPlusEngine::initialized' . . . collect2: ld returned 1 exit status make: *** [Maple] Error 1 The vertical three dots hold place for a series of "undefined reference to..." errors, which are similar to the first error, but specify a different member of
CursesPlusEngine
. And to make it clear: Maple is my main executable project, and libCursesPlus is my library project. --Edit-- All of the above members are defined as private static in their corresponding header files.modified on Tuesday, August 31, 2010 4:56 AM
No! You may declare your static class members only once. What you have missed, is the definition (which also has to be unique), and it needs to be provided outside of the class, for non-const and non-trivial objects.
// in AStuff.h
class AStuff {
public:
void Hello() {
// ...
}
};// in A.h
class A {
public:
static AStuff sStaticAMember; // <-declaration
};// in A.cpp
AStuff A::sStaticAMember; //<-definition (required!)The constructor for
A::sStaticAMember
will be called by the runtime (dynamic initialization) if the instance is used by the program. You do not (really) have the control over when this is going to happen, neither when the destructor is going to be called. This is one of the reason why the poster above damned "statics" ... and basically I have to agree with him. Are you using C# otherwise? If yes, then forget about the comfort of static class objects and their well defined initialization there - and enter one of the many dark zones of c++. I assume you will probably run into the problem of undefined order of initializations of your non-local objects, but we stand ready to help :)modified on Tuesday, August 31, 2010 12:56 PM
-
When you declare a static data member in a class you're telling the compiler: "This class has a static member called ." When you define it outside of a class you're telling the compiler: "You know that variable ? This is where you reserve memory for it and initialise it with ." So it really is identically like a function which is declared in a header and defined in the source. Cheers, Ash PS: It's also identical to the behaviour of global variables - declare in a header, define in source. Which is a big hint why statics are bad, bad, bad...
Aescleal wrote:
PS: It's also identical to the behaviour of global variables - declare in a header, define in source. Which is a big hint why statics are bad, bad, bad...
That's a rather sweeping statement. Parts of the language are there for a reason. There are cases where you absolutely need them. Can you misuse them? Certainly. But just yelling bad, bad, bad, ignores the valid cases.
Once you agree to clans, tribes, governments...you've opted for socialism. The rest is just details.
-
Aescleal wrote:
PS: It's also identical to the behaviour of global variables - declare in a header, define in source. Which is a big hint why statics are bad, bad, bad...
That's a rather sweeping statement. Parts of the language are there for a reason. There are cases where you absolutely need them. Can you misuse them? Certainly. But just yelling bad, bad, bad, ignores the valid cases.
Once you agree to clans, tribes, governments...you've opted for socialism. The rest is just details.
So where would you use a class static instead of just declaring a variable in an anonymous namespace? i.e. where would you use:
// A.h
class A
{
private:
static B b;
};// A.cpp
A::B b( b_init );
over:
// A.cpp
namespace
{
B b;
}'Cause I'm not sure I can see any case where that would be of any use. And if you're talking about using public class static data member why not use a global? They've got exactly the same visibility, thread safety issues and initialisation order problems.
-
So where would you use a class static instead of just declaring a variable in an anonymous namespace? i.e. where would you use:
// A.h
class A
{
private:
static B b;
};// A.cpp
A::B b( b_init );
over:
// A.cpp
namespace
{
B b;
}'Cause I'm not sure I can see any case where that would be of any use. And if you're talking about using public class static data member why not use a global? They've got exactly the same visibility, thread safety issues and initialisation order problems.
Aescleal wrote:
So where would you use a class static instead of just declaring a variable in an anonymous namespace?
...Whenever the non-local is associated with a type, think of the "class object" idioms: reflectors, serializers, registrars etc... Especially in generic code, class statics can be looked up parametrically, which can't be achieved with traditional non-locals.
Aescleal wrote:
They've got exactly the same visibility, thread safety issues and initialisation order problems
This remains true and makes c++ non-locals of either kind a dangerous business...
-
So where would you use a class static instead of just declaring a variable in an anonymous namespace? i.e. where would you use:
// A.h
class A
{
private:
static B b;
};// A.cpp
A::B b( b_init );
over:
// A.cpp
namespace
{
B b;
}'Cause I'm not sure I can see any case where that would be of any use. And if you're talking about using public class static data member why not use a global? They've got exactly the same visibility, thread safety issues and initialisation order problems.
I suppose the classic example is where you want to keep stats on the class such has how many instances are currently running rampant. Why should I have to go reference another namespace? Like many things in the C world, there's plenty there to shoot yourself in the foot with, you need to exercise proper caution.
Once you agree to clans, tribes, governments...you've opted for socialism. The rest is just details.
-
No! You may declare your static class members only once. What you have missed, is the definition (which also has to be unique), and it needs to be provided outside of the class, for non-const and non-trivial objects.
// in AStuff.h
class AStuff {
public:
void Hello() {
// ...
}
};// in A.h
class A {
public:
static AStuff sStaticAMember; // <-declaration
};// in A.cpp
AStuff A::sStaticAMember; //<-definition (required!)The constructor for
A::sStaticAMember
will be called by the runtime (dynamic initialization) if the instance is used by the program. You do not (really) have the control over when this is going to happen, neither when the destructor is going to be called. This is one of the reason why the poster above damned "statics" ... and basically I have to agree with him. Are you using C# otherwise? If yes, then forget about the comfort of static class objects and their well defined initialization there - and enter one of the many dark zones of c++. I assume you will probably run into the problem of undefined order of initializations of your non-local objects, but we stand ready to help :)modified on Tuesday, August 31, 2010 12:56 PM
This is all a bit overwhelming for me... I also read some articles regarding the subject, but I still can't <b><i>completely</i></b> get my head around it. I should hit the books for a while and establish a more solid understanding of C++'s principles and design issues. For now, I would add this question though... What is the "danger" in what I did? i.e. declaring a private static member variable inside a class...
-
I suppose the classic example is where you want to keep stats on the class such has how many instances are currently running rampant. Why should I have to go reference another namespace? Like many things in the C world, there's plenty there to shoot yourself in the foot with, you need to exercise proper caution.
Once you agree to clans, tribes, governments...you've opted for socialism. The rest is just details.
Tim Craig wrote:
I suppose the classic example is where you want to keep stats on the class such has how many instances are currently running rampant.
Yes, this is a classic one, where a static member must be associated with a class... As an example to the generic argument from above, consider an
InstanceCountabe
policy:template<class T>
class InstanceCountable { :)
static int sCounter;
protected:
InstanceCountable() {
InstanceCountable<T>::sCounter++;
}
~InstanceCountable() {
InstanceCountable<T>::sCounter--;
}
public:
static GetCount() {
return InstanceCountable<T>::sCounter;
}
};template<class T>
int InstanceCountable<T>::sCounter(0);// ...and then
class A : public InstanceCountable<A> {
//...
};class B : public InstanceCountable<B> {
//...
};// etc...
int main() {
A a1, a2;
std::array<B, 10> barr;std::cout <<
A::GetCount() << std::endl // prints 2
B::GetCount() << std::endl;// prints 10
} -
This is all a bit overwhelming for me... I also read some articles regarding the subject, but I still can't <b><i>completely</i></b> get my head around it. I should hit the books for a while and establish a more solid understanding of C++'s principles and design issues. For now, I would add this question though... What is the "danger" in what I did? i.e. declaring a private static member variable inside a class...
Well, there are several "dangers" in that, but don't panic! It's a perfectly legal c++ construct - which can be used in safe manner if: 1. the functionality of your program does not depend on the time when the global objects are initialized/deinitialized 2. the globals do not depend on the state of each other in an undefined manner 3. you can assure that these global objects are initialized at all - speaking in terms of the holy standard "they are used in the program". With regards to point 3: Under certain circumstances, linkers do not include these globals into the program, if they don't see an explicit usage of them. This behavior collides with many popular idioms such as pluggable factories, reflectors or serializers: Here, the framework relies on dynamic initialization (this is a process which runs before your program starts) of static class objects with non-trivial constructors which perform certain functionality on instantiation - e.g. register a factory method for a type in an another global collection of factory methods.
-
Well, there are several "dangers" in that, but don't panic! It's a perfectly legal c++ construct - which can be used in safe manner if: 1. the functionality of your program does not depend on the time when the global objects are initialized/deinitialized 2. the globals do not depend on the state of each other in an undefined manner 3. you can assure that these global objects are initialized at all - speaking in terms of the holy standard "they are used in the program". With regards to point 3: Under certain circumstances, linkers do not include these globals into the program, if they don't see an explicit usage of them. This behavior collides with many popular idioms such as pluggable factories, reflectors or serializers: Here, the framework relies on dynamic initialization (this is a process which runs before your program starts) of static class objects with non-trivial constructors which perform certain functionality on instantiation - e.g. register a factory method for a type in an another global collection of factory methods.