LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-15-2005, 03:54 AM   #1
ChemicalBurn
LQ Newbie
 
Registered: Feb 2005
Posts: 28

Rep: Reputation: 15
Namespaces


To use an already existing namespace, is there anything else you need to do besides the "using namespace NAMESPACE;" statement?
Because Im using certain objects that are within a namespace, but when I call their functions, the compiler cannot link them and does not find the references.
 
Old 02-15-2005, 08:28 AM   #2
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
Are you linking the library/object where the object code for those functions is at? More details would be nice.
 
Old 02-15-2005, 08:32 AM   #3
ChemicalBurn
LQ Newbie
 
Registered: Feb 2005
Posts: 28

Original Poster
Rep: Reputation: 15
what do you mean linking? that was pretty much my question... I havent used C++ in a very long time, and even then didnt get into too much detail. I basically have the files included in the code.
 
Old 02-15-2005, 08:46 AM   #4
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
There are a few stages that occur while building a binary from source code. First is the pre-processor, then the compiler, then the linker.

The compiler basically converts your source code to object code, linking combines all that object code into a single binary. The linking stage is where it will be found if you are calling functions that you do not have any object code for.

Now, here's where the difference comes between a header file and a library. Header files are only declarations of functions and objects. They do not contain a full implementation of those functions/objects, so no object code can be generated from the header file alone. The libraries are where the actual object code will be located.

Now, since you give absolutely no details on what functions are not being found, we can only speculate on what the problem is. I can think of 1 of 3 scenarios off the top of my head.
  • You are using a library other than a standard C/C++ library and not linking it
  • You are using multiple source files and trying to link against only one of them.
  • You are using gcc to compile C++ code instead of g++, and it isn't finding the C++ libraries because gcc is a C compiler and won't link those by default.

For the first case, I will use an example of OpenGL. If you were using OpenGL, at the top of the source files that you are using OpenGL functions from you would have:

#include <GL/gl.h>

Note that this does NOT include the library, only the declarations of functions that can be found in the library.

To compile my theoretical OpenGL app, you would have to use the following:

g++ somefile.c -o somebinary -lGL

Note the -lGL. That basically will get passed to the linker, telling it that it needs to link with the libGL.so library. (Drop the lib and .so part and append the -l to add any particular library)

It will search for libGL.so in a few various paths, and if it is outside that path, you also need to specify -L/path/to/library, which will add that path to the list of library search paths.

For the second case, you need to do something like so:

g++ file1.cpp file2.cpp -o binary

Or:

g++ -c file1.cpp -o file1.o
g++ -c file2.cpp -o file2.o
g++ file1.o file2.o -o binary

For the third case, just use g++ instead of gcc.
 
Old 02-15-2005, 08:58 AM   #5
ChemicalBurn
LQ Newbie
 
Registered: Feb 2005
Posts: 28

Original Poster
Rep: Reputation: 15
Thanks, I understand what you mean, and Im sorry there's no code, Ill add some now, but I cant add the whole object code Im using because its too big. Now the thing is that Im using KDevelop, so it should be linking on its own, and I am using g++.
Im continuing a project started by someone else, and he was also building using the same library Im using, and Im declaring the objects same way they are declared in his code, but I am recieving this error. AND whats even more confusing is that some objects work and others do not.
Basically the library is a graph library, Im using it for network simulation, The List object works fine unlesss I use the list template to create lists of for example "edges" There whenever I call on a function within this class it gives me the following error:
main.o(.text+0x243): In function `main':
: undefined reference to `TeEdgeType::SetWorkingCapacity(double)'
collect2: ld returned 1 exit status
although I have the TeEdgeType header file included. And I created a list of TeEdges, unless I try to access a function from within this class, no errors occur.

TeEdge te;

List<TeEdge> TeEdgeList1;
TeEdgeList1.PushBack(te);
TeEdgeList1.PushBack(te);
TeEdgeList1.PushBack(te);
This works fine...
But te->SetWorkingCapacity(2.0); which is a method in the class does not work

I've been busting my head on this for a week now...

Last edited by ChemicalBurn; 02-15-2005 at 09:00 AM.
 
Old 02-15-2005, 11:02 AM   #6
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
Quote:
Originally posted by ChemicalBurn
Now the thing is that Im using KDevelop, so it should be linking on its own, and I am using g++.
I haven't had a lot of experience with KDevelop, but I seem to remember somewhere there is a location to add additional libraries to link to. KDevelop won't just magically know which external libraries your code uses.

Is the TeEdge class one that is in the project you are using, or is it in another library? Somehow you are not giving the object code for that class (or at least not that function in the class) to the linker.

Since you are using templates it opens up another possibility. It doesn't appear that this is probably the case since it doesn't look like TeEdge itself is a template class (unless it is a typedef for a template specialization), but it's something that's worth mention anyway.

Template code is only compiled when a "specialization" is created. That is, when you give a concrete type for any templatized parameters. Each function of a template class is also only compiled when it is used. Because of this, the compiler needs to know the full implementation of the template class at compile time, not at link time. This is probably a bit of a simplification but the results are the same. The full definition of a template class must be in the header. (e.g. You can't have a separate .h and .cpp to separate declaration and definition like you can with non-template classes.)

Last edited by deiussum; 02-15-2005 at 11:06 AM.
 
Old 02-16-2005, 04:07 AM   #7
ChemicalBurn
LQ Newbie
 
Registered: Feb 2005
Posts: 28

Original Poster
Rep: Reputation: 15
The template class header file uses a .tpp file for definitions of the functions. And yes the TeEdge is a typedef for a template specialization.
I tried something else now though. I opened the previos project which Im uses that same library but functions fine, and I created a new class (added new class to project) called classadded2 Here's the code:
Header file:
Code:
#include <iostream>
#include "InputReader.h"
#include "GRAPH/Graph.h"
#include "DemandNodeType.h"
#include "DemandEdgeType.h"

class classadded2 {
public: 
	classadded2();
        classadded2(int x);
	~classadded2();

  Graph<DemandNode,DemandEdge>& _demandGraph;
  void returningDemandGraph(InputReader& _ir);
  
};
Cpp file:
Code:
#include "classadded2.h"

classadded2::classadded2(){
}
classadded2::classadded2(int x){
  int n = x;
}

classadded2::~classadded2(){
}

filebuf buf;
ostream outf(&buf);
InputReader& ir("cost239_conf.gml","pp",outf,&buf,1);

void  classadded2::returningDemandGraph(InputReader& _ir){
  std::cout<<"IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII"<<endl;
  _demandGraph = _ir.GetDemandGraph();
  std::cout<<"IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII"<<endl;
}
(DemandEdge and DemandNode are typedefs of the template classes)
Now I'm simply trying to call the Function rturningDemandGraph from a different class. This is how I initialize the objects.. When I initialized this exact same way in another project, it ran perfectly fine. and here everything compiles fine untill I call the function returningDemandGraph.
In the header file of the class that will call the function I have:
#include "classadded2.h"
classadded2 ca2;
and in the .cpp file:
ca2.returningDemandGraph(ir);
also tried in the .cpp:
classadded2 ca2();.
classadded2 ca2 = classadded2(); (after removing the declaration from the header of course.)

and same as before... I get this:
Simulator.o(.text+0x54): In function `Simulator::~Simulator [not-in-charge]()':
/usr/include/g++/bits/stl_tree.h:166: undefined reference to `classadded2::~classadded2 [in-charge]()'
Simulator.o(.text+0x74): In function `Simulator::~Simulator [in-charge]()':
/usr/include/g++/bits/basic_string.h:728: undefined reference to `classadded2::~classadded2 [in-charge]()'
Simulator.o(.text+0x95): In function `Simulator::~Simulator [in-charge deleting]()':
/usr/include/g++/i586-suse-linux/bits/atomicity.h:38: undefined reference to `classadded2::~classadded2 [in-charge]()'
Simulator.o(.text+0x273): In function `Simulator::Runs(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, int)':
/usr/include/g++/bits/basic_string.h:249: undefined reference to `classadded2::returningDemandGraph(InputReader&)'
Simulator.o(.text+0x14): In function `Simulator::Simulator[not-in-charge]()':
/usr/include/g++/bits/stl_tree.h:1036: undefined reference to `classadded2::classadded2[in-charge]()'
Simulator.o(.text+0x34): In function `Simulator::Simulator[in-charge]()':
/usr/include/g++/bits/basic_string.h:249: undefined reference to `classadded2::classadded2[in-charge]()'
collect2: ld returned 1 exit status
make: *** [examp] Error 1


I appreciate all the help, I know this is getting irritating...

Last edited by ChemicalBurn; 02-16-2005 at 04:48 AM.
 
Old 02-16-2005, 04:58 AM   #8
ChemicalBurn
LQ Newbie
 
Registered: Feb 2005
Posts: 28

Original Poster
Rep: Reputation: 15
ok you were right, its not linking the classadded.o to the rest of the project, but how do I link it. I saw this because the make output is:
/bin/sh ../libtool --mode=link g++ -g -O2 -o examp -L/home/j_ghibril/GRAPH-v2.0/lib ConfigEdgeType.o ConfigNodeType.o DemandEdgeType.o DemandNodeType.o InputReader.o LspEdgeType.o LspNodeType.o main.o OutputWriter.o Sim.o Simulator.o Statistics.o TeEdgeType.o TeNodeType.o FiberEdgeType.o FiberNodeType.o -lGRAPH
g++ -g -O2 -o examp ConfigEdgeType.o ConfigNodeType.o DemandEdgeType.o DemandNodeType.o InputReader.o LspEdgeType.o LspNodeType.o main.o OutputWriter.o Sim.o Simulator.o Statistics.o TeEdgeType.o TeNodeType.o FiberEdgeType.o FiberNodeType.o -L/home/j_ghibril/GRAPH-v2.0/lib -lGRAPH
so classadded.o is not there. I mean the file has not been created in the first place. What can I do?

Last edited by ChemicalBurn; 02-16-2005 at 05:04 AM.
 
Old 02-16-2005, 08:48 AM   #9
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
Somehow you have to tell KDevelop to compile the classadded class as part of the project. I have not used KDevelop much so I can't specifically say how to do that. If you were working directly with Makefiles, you would simply have to add it to your list of objects that is compiled/linked into your final binary. If I get the time, I may pull up KDevelop again for a bit to look at it's interface.

You said that the functions for the template classes are implemented in a .tpp file? I don't see your new class including that anywhere, is it included in the header? Again, the full definition of the class must be defined at compile time. Each .cpp file is essentially compiled on its own first, then linked into the final binary. So try tracking back the #includes of the .cpp giving you the trouble and make sure that the compiler would somehow include the full definition of the function via #includes.
 
Old 02-16-2005, 09:28 AM   #10
ChemicalBurn
LQ Newbie
 
Registered: Feb 2005
Posts: 28

Original Poster
Rep: Reputation: 15
I really appreciate all the help. I finally figured it out, like you said, I had to manually include the classadded to the compiled list of files, for some reason it was not linking it. Though somehow if there were syntax errors in the file it displayed them during make, but for some reason it was not creating the .o file for the class and not linking it to the rest.
Anyways... I think eventually I might have to figure out how to do it automatically through KDevelop.
Thanks.
 
Old 02-16-2005, 09:49 AM   #11
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
No problem. Glad you got it working.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
C++: recursive #including: partial namespaces? R00ts Programming 4 03-09-2005 12:15 AM
using multiple namespaces over in C++ R00ts Programming 1 09-22-2004 04:15 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:28 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration