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 12-28-2010, 01:00 PM   #1
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443
Blog Entries: 3

Rep: Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723
C++ linking error


I got this huge linking error while compiling some C++ code I wrote (it uses boost::regex):

Code:
$ g++ test.cc mapfile.cc
/tmp/cckQHPu1.o: In function `main':
test.cc:(.text+0x169): undefined reference to `mapfile::write(std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&, std::basic_ofstream<char, std::char_traits<char> >&)'
/tmp/ccCgsp1F.o: In function `boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::assign(char const*, char const*, unsigned int)':
mapfile.cc:(.text._ZN5boost11basic_regexIcNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEE6assignEPKcS7_j[boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::assign(char const*, char const*, unsigned int)]+0x2e): undefined reference to `boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::do_assign(char const*, char const*, unsigned int)'
/tmp/ccCgsp1F.o: In function `bool boost::regex_match<char const*, std::allocator<boost::sub_match<char const*> >, char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >(char const*, char const*, boost::match_results<char const*, std::allocator<boost::sub_match<char const*> > >&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags)':
mapfile.cc:(.text._ZN5boost11regex_matchIPKcSaINS_9sub_matchIS2_EEEcNS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEEEbT_SA_RNS_13match_resultsISA_T0_EERKNS_11basic_regexIT1_T2_EENS_15regex_constants12_match_flagsE[bool boost::regex_match<char const*, std::allocator<boost::sub_match<char const*> >, char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >(char const*, char const*, boost::match_results<char const*, std::allocator<boost::sub_match<char const*> > >&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags)]+0x80): undefined reference to `boost::re_detail::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::match()'
/tmp/ccCgsp1F.o: In function `boost::re_detail::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::perl_matcher(char const*, char const*, boost::match_results<char const*, std::allocator<boost::sub_match<char const*> > >&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags, char const*)':
mapfile.cc:(.text._ZN5boost9re_detail12perl_matcherIPKcSaINS_9sub_matchIS3_EEENS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEEC2ES3_S3_RNS_13match_resultsIS3_S6_EERKNS_11basic_regexIcSA_EENS_15regex_constants12_match_flagsES3_[_ZN5boost9re_detail12perl_matcherIPKcSaINS_9sub_matchIS3_EEENS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEEC5ES3_S3_RNS_13match_resultsIS3_S6_EERKNS_11basic_regexIcSA_EENS_15regex_constants12_match_flagsES3_]+0xf6): undefined reference to `boost::re_detail::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::construct_init(boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags)'
/tmp/ccCgsp1F.o: In function `boost::re_detail::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::unwind_extra_block(bool)':
mapfile.cc:(.text._ZN5boost9re_detail12perl_matcherIPKcSaINS_9sub_matchIS3_EEENS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEE18unwind_extra_blockEb[boost::re_detail::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::unwind_extra_block(bool)]+0x69): undefined reference to `boost::re_detail::put_mem_block(void*)'
/tmp/ccCgsp1F.o: In function `boost::re_detail::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::match_match()':
mapfile.cc:(.text._ZN5boost9re_detail12perl_matcherIPKcSaINS_9sub_matchIS3_EEENS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEE11match_matchEv[boost::re_detail::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::match_match()]+0x25c): undefined reference to `boost::match_results<char const*, std::allocator<boost::sub_match<char const*> > >::maybe_assign(boost::match_results<char const*, std::allocator<boost::sub_match<char const*> > > const&)'
/tmp/ccCgsp1F.o: In function `void boost::re_detail::raise_error<boost::regex_traits_wrapper<boost::regex_traits<char, boost::cpp_regex_traits<char> > > >(boost::regex_traits_wrapper<boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::error_type)':
mapfile.cc:(.text._ZN5boost9re_detail11raise_errorINS_20regex_traits_wrapperINS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEEEEEvRKT_NS_15regex_constants10error_typeE[void boost::re_detail::raise_error<boost::regex_traits_wrapper<boost::regex_traits<char, boost::cpp_regex_traits<char> > > >(boost::regex_traits_wrapper<boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::error_type)]+0x4d): undefined reference to `boost::re_detail::raise_runtime_error(std::runtime_error const&)'
/tmp/ccCgsp1F.o: In function `boost::re_detail::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::extend_stack()':
mapfile.cc:(.text._ZN5boost9re_detail12perl_matcherIPKcSaINS_9sub_matchIS3_EEENS_12regex_traitsIcNS_16cpp_regex_traitsIcEEEEE12extend_stackEv[boost::re_detail::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::extend_stack()]+0x36): undefined reference to `boost::re_detail::get_mem_block()'
/tmp/ccCgsp1F.o: In function `boost::cpp_regex_traits<char>::transform(char const*, char const*) const':
mapfile.cc:(.text._ZNK5boost16cpp_regex_traitsIcE9transformEPKcS3_[boost::cpp_regex_traits<char>::transform(char const*, char const*) const]+0x38): undefined reference to `boost::re_detail::cpp_regex_traits_implementation<char>::transform(char const*, char const*) const'
/tmp/ccCgsp1F.o: In function `boost::cpp_regex_traits<char>::transform_primary(char const*, char const*) const':
mapfile.cc:(.text._ZNK5boost16cpp_regex_traitsIcE17transform_primaryEPKcS3_[boost::cpp_regex_traits<char>::transform_primary(char const*, char const*) const]+0x38): undefined reference to `boost::re_detail::cpp_regex_traits_implementation<char>::transform_primary(char const*, char const*) const'
/tmp/ccCgsp1F.o: In function `boost::re_detail::cpp_regex_traits_implementation<char>::error_string(boost::regex_constants::error_type) const':
mapfile.cc:(.text._ZNK5boost9re_detail31cpp_regex_traits_implementationIcE12error_stringENS_15regex_constants10error_typeE[boost::re_detail::cpp_regex_traits_implementation<char>::error_string(boost::regex_constants::error_type) const]+0xa6): undefined reference to `boost::re_detail::get_default_error_string(boost::regex_constants::error_type)'
mapfile.cc:(.text._ZNK5boost9re_detail31cpp_regex_traits_implementationIcE12error_stringENS_15regex_constants10error_typeE[boost::re_detail::cpp_regex_traits_implementation<char>::error_string(boost::regex_constants::error_type) const]+0xfe): undefined reference to `boost::re_detail::get_default_error_string(boost::regex_constants::error_type)'
collect2: ld returned 1 exit status
The sources are attached. BTW, how is it possible to diagnose linker errors, especially when they don't have line numbers?
Attached Files
File Type: txt test.cc.txt (336 Bytes, 18 views)
File Type: txt mapfile.hh.txt (343 Bytes, 18 views)
File Type: txt mapfile.cc.txt (2.4 KB, 14 views)
 
Old 12-28-2010, 01:42 PM   #2
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
The obvious error in your code is that your .hh file declares read and write inside namespace mapfile, while your mapfile.cc file defines them outside of any namespace.

But for all your non obvious errors, I have no clue. I'm not a fan of boost, so I don't use it much and I wouldn't know without research what is wrong with your use of it.

Last edited by johnsfine; 12-28-2010 at 01:46 PM.
 
Old 12-28-2010, 01:43 PM   #3
orgcandman
Member
 
Registered: May 2002
Location: new hampshire
Distribution: Fedora, RHEL
Posts: 600

Rep: Reputation: 110Reputation: 110
It helps to read the error message. You didn't tell the linker that you are linking to the boost library. It's not a compile time error, but a link time error (hence why there are no line numbers). You see all the 'undefined reference' messages; that should be a clue.

I believe you should add -lboost to your g++ line, but am not 100% sure what the exact library name is. Check the documentation.

Additionally, johnsfine pointed out something I overlooked completely.

Last edited by orgcandman; 12-28-2010 at 01:44 PM.
 
Old 12-28-2010, 01:49 PM   #4
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 374Reputation: 374Reputation: 374Reputation: 374
Quote:
BTW, how is it possible to diagnose linker errors, especially when they don't have line numbers?
They don't give line numbers because your source code is syntactically correct. Whether your syntax accomplishes what you expect is a separate question. It's just like putting a puzzle together. Multiple pieces may fit together to form larger blocks, but if the larger blocks don't fit when put together, where is the problem? Is it the orientation of the large blocks or is it the individual pieces? If the individual pieces, which piece? (because they all appear to fit together correctly) There are multiple possibilities for the root cause of the error, and no way of identifying which is the "true" cause.

To debug, you look at the error messages and start at the top:
Code:
test.cc:(.text+0x169): undefined reference to `mapfile::write(std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&, std::basic_ofstream<char, std::char_traits<char> >&)'
Open test.cc, and we have:
Code:
mapfile::write(m, f);
Open mapfile.hh, and we have:
Code:
namespace mapfile
{

std::map<std::string, std::string>* read(std::ifstream file);

void write(std::map<std::string, std::string> &m, std::ofstream &file);

}
Open mapfile.cc, and we have:
Code:
using namespace std;
. . .
void write(const map<string, string> & m, ofstream & file)
{
. . .
}
Now, I'm no expert on namespaces, but it looks to me like you declared a write function in the mapfile namespace, but when you wrote the function's implementation, you did not specify the mapfile namespace. Without specifying it, the function defaulted to the std namespace. Perhaps it should be:
Code:
void mapfile::write(const map<string, string> & m, ofstream & file)
You'll need to do the same for the read function as well. The other errors regarding boost stuff can probably be fixed by adding "-lboost" to the g++ command line. Though, you may need to do some reading to find out exactly what the library name is that you need to link against.

EDIT:
Beaten to the punch on both points...
 
Old 12-28-2010, 01:52 PM   #5
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by orgcandman View Post
You didn't tell the linker that you are linking to the boost library. It's not a compile time error, but a link time error (hence why there are no line numbers).
The fact that the error is not reported until link time does not necessarily mean it is an error in the way the program is linked (such as a missing library). In this case, I doubt the problem is a missing library.

In code with messy templating (most of boost) it is very hard to get certain errors to show up at the right time or in an understandable form.

If you pass an impossible parameter type to an ordinary function, the compiler can easily report an understandable error. Also if you pass a nearly right parameter type to an ordinary function, the compiler has a wide range of automatic casts it can use to try to get to the right type.

But passing the wrong parameter type to a function whose parameters are templated (most boost functions) gives the compiler no good way to identify and report your error.

There are extra complications to passing a quoted string as a parameter for which the type must be inferred from a template definition.

I don't know what the parameter type is for boost::regex::assign but a quick look at your error messages makes me suspect the quoted strings in
Code:
    re_blank.assign("^(\\s*|#.*)$");
    re_oneline.assign("^([^:]):\\s+(.+)$");
    re_multiline.assign("^([^:])::\\s+(.+)$");
But remember, I'm not a boost expert, so mainly I'm guessing here.

Last edited by johnsfine; 12-28-2010 at 01:59 PM.
 
Old 12-28-2010, 03:02 PM   #6
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443

Original Poster
Blog Entries: 3

Rep: Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723
Quote:
Originally Posted by Dark_Helmet View Post
Now, I'm no expert on namespaces, but it looks to me like you declared a write function in the mapfile namespace, but when you wrote the function's implementation, you did not specify the mapfile namespace. Without specifying it, the function defaulted to the std namespace. Perhaps it should be:
Code:
void mapfile::write(const map<string, string> & m, ofstream & file)
Didn't help.

Quote:
Originally Posted by Dark_Helmet View Post
You'll need to do the same for the read function as well. The other errors regarding boost stuff can probably be fixed by adding "-lboost" to the g++ command line. Though, you may need to do some reading to find out exactly what the library name is that you need to link against.
Code:
/usr/bin/ld: cannot find -lboost
collect2: ld returned 1 exit status
 
Old 12-28-2010, 03:25 PM   #7
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 374Reputation: 374Reputation: 374Reputation: 374
Quote:
Originally Posted by MTK358
Didn't help.
Well, like I said, I'm not an expert on namespaces. You need to go find a resource that explains what the correct syntax is to not only declare the function as part of a namespace, but to also write the implementation in the proper namespace.

My only experience with namespaces is when dealing with classes:
Code:
class clBaseObject
{
  public:
    unsigned GetID( void );
  private:
    unsigned objectID;
};

unsigned clBaseObject::GetID( void )
{
  return objectID;
}
Quote:
Originally Posted by MTK358
Code:
/usr/bin/ld: cannot find -lboost
collect2: ld returned 1 exit status
The "-lboost" was a guess. You need to review the boost documentation to find out how to include their code with your program. I don't use it. So I don't know. Typically, the method is to add "-l<somename>" to the g++/gcc command line. You replace <somename> with whatever the docs tell you. If you don't have any boost documentation, a Google search for a boost tutorial ought to get you the info you need.

Last edited by Dark_Helmet; 12-28-2010 at 03:26 PM.
 
Old 12-28-2010, 03:59 PM   #8
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by Dark_Helmet View Post
Well, like I said, I'm not an expert on namespaces. You need to go find a resource that explains what the correct syntax is to not only declare the function as part of a namespace, but to also write the implementation in the proper namespace.
Defining in a namespace uses the same syntax as declaring in a namespace. (Your suggestion extrapolated the way things work for a class in a way that is not correct for a namespace).

Before the definitions you put
Code:
namespace mapfile {
After the definitions, you put the closing
Code:
}
 
  


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
Linking Error sheenak Programming 1 07-11-2004 11:52 PM
Linking error sheenak Programming 2 05-31-2004 07:04 AM
error while linking... trouby Linux - Software 0 10-15-2003 05:18 PM
Linking error using g++ Musikolo Linux - Software 0 07-23-2003 12:54 PM
libpcap linking error Hammo Linux - Networking 5 02-20-2003 07:20 AM

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

All times are GMT -5. The time now is 04:55 PM.

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