哪些情况会导致"Undefined Reference Error"

“Undefined Reference Error” 是在程序链接(link)时经常遇到的错误,字面意思来说就是没有找到已经定义的引用,在编译器无法找到用户所使用的变量或函数:

一、缺失头文件

例如声明变量 uint64_t tmp,但没有在开头包含 #include<stdint.h>

例如使用 memset() 需要包含头文件 string.h 或 memory.h

二、缺失目标文件或者库文件(.a .o .so …)

编译器查找用户函数,首先会在本文件中的函数中找,然后在系统环境变量定义的目标文件/库(.a .o .so …)文件中找,最后在链接的目标文件/库文件(.a .o .so …)中寻找用户函数;如果没有找到则报”Undefined Reference Error”错

四、库(目标)文件链接顺序有误

库文件的链接顺序是:依赖的库A 放后面,被依赖的库B 放前面。如果A 和B 相互依赖,则使用A B A 或者B A B 的。

例如main 文件中引用func 文件中函数,则编译顺序为main.o func.o

五、C 函数和C++函数引用问题

C++ 程序链接时可以链接C 的库文件,但在.cc(.cpp) 中引用头文件时需要通过extern “C”{ #include “func.h”} 的方式引用该头文件,否则会提示”Undefined Reference Error”

C 程序无法链接C++ 库文件,否则会提示”Undefined Reference Error”,找不到引用C++ 函数的引用

参考:http://blog.csdn.net/aiwoziji13/article/details/7330333

重载类型转换符

C++ 程序员都知道重载运算符:

   1: operator++

   2: operator==

   3: operator>>

比如C++ 中的输入输出:

   1: cout<<"Hello World!"<<endl;

   2: cin>>&value>>endl;

 

实际上就是重载了”>>” 和”<<”  运算法,但如果说重载类型转换符,可能不是所有的程序员都用到过,最近写一个配置文件的类就碰到了这样的问题。我希望使用 template<class T> T Config::string_to_T(const string& s) 函数返回指定类型的参数,T 类型由调用string_to_T() 的函数确定。比如:

   1: template<class T> T Config::Read(const string& key, const T& value)const{

   2:     ....from key we get value...

   3:     return string_to_T<T>(value);

   4: }

下面是我写的代码:

   1: template<class T> T Config::string_to_T(const string& s){

   2:     T t;

   3:  

   4:     istringstream ist(s);

   5:     ist >> t;

   6:  

   7:     return t;

   8: }

这段代码在大部分时候是没有问题的。

   1: int port

   2: port = Read("port", 0) \\返回了int 类型的端口号

   3: string ip

   4: Read("ip", ip)         \\返回了string 类型的ip 地址

但在T 类型为string 类型的时候,如果s 中包含了空格,那么返回的string 类型只包含了string value 的一部分。比如:

   1: str num_list

   2: port = Read("nums", num_list) \\num 如果对应的值是"1 2 3 4",那么则只返回 1

这是因为ist >> t 格式化输出到T t,当遇到有空格时会将string 分开输出。

解决方法也非常简单,就是的当类型为string 时直接返回,当不是string 类型时,通过上面的string_to_T() 方法即可,这就需要重载类型转换符,代码如下(operator std::string()const  和template<template T> operator T()const 分别重载了string() 和T() 类型转化符):

   1: class ToStringHelper

   2: {

   3:     std::string myValue;

   4: public:

   5:     ToStringHelper( std::string const& value )

   6:         : myValue( value )

   7:     {

   8:     }

   9:     operator std::string() const

  10:     {

  11:         return myValue;

  12:     }

  13:     template <typename T>

  14:     operator T() const

  15:     {

  16:         std::istringstream cvt( myValue );

  17:         T results;

  18:         cvt >> results;

  19:         //  Error checking here...

  20:         return results;

  21:     }

  22: };

  23:  

  24: ToStringHelper

  25: string_to_T( std::string const& s )

  26: {

  27:     return ToStringHelper( s );

  28: }

 

我的提问stackoverflow:http://stackoverflow.com/questions/13658667/how-can-i-return-a-string-as-a-template-class-in-c/

链接任意目录下库文件(解决错误“/usr/bin/ld: cannot find -lxxx”)

g++ 编译中链接库文件选项有: -L **  -lxxx

其中 -L 告诉编译器哪里去寻找库文件,** 指的是库文件所在路径,xxx 是库文件的名称,那么-lxxx 告诉编译器去找库文件libxxx.a(而不是xxx.a)。

如果生成的库文件时bplus.a ,就需要将其重命名为libbplus.a 这样才会找到该文件。否则,报如下错误

/usr/bin/ld: cannot find -lbplus
collect2: ld returned 1 exit status

继续阅读