c++ - 在我的函数中使用简单类时出现 undefined reference 错误

标签 c++ gcc linker g++ poco

我对这个错误很生气,所以我想一些更有经验的开发人员可以在这方面帮助我。 我正在尝试编译一个使用 C++ 库(名为 Poco)的示例项目。我的项目链接到已编译的 poco 库。

下面是我的(最简化的)代码:

#include "Poco/UUID.h"
class x
{
    void func1()                                        
    {                                                                           
        new Poco::UUID();  //A
    }   
};

void func1()                                        
{                                                                           
    new Poco::UUID();   //B
}

现在编译上面的代码时,“A”行没有错误,但对于“B”行,链接器说: 对 `Poco::UUID::UUID()' 的 undefined reference

这是什么原因?当我在类方法中从外部库实例化一个类时,没有发生错误,但函数中的相同代码会产生链接器错误? (当我注释行B时,没有错误发生并且生成了链接器输出文件)

我的配置:Win7/g++/CodeLite/MinGW-4.7.1

*更新 2:*谢谢。我的问题现在已解决,问题是我在使用 g++(均在 Windows 平台下)编译应用程序时使用 MSVC 编译器编译了库。所以我使用 g++ 重新编译了库,现在一切正常。

更新 1:这是我构建项目时 IDE 的输出:

    C:\Windows\system32\cmd.exe /c "mingw32-make.exe -j 4 -e -f  "dll1.mk"  all"
----------Building project:[ dll1 - Debug ]----------
g++ -shared -fPIC -o ./Debug/dll1.so @"dll1.txt" -L. -Lc:/poco/lib  -lPocoFoundationd
./Debug/PluginLibrary.o: In function `Z5func1v':
C:/Users/PARS/Documents/codelite/workspace1/dll1/PluginLibrary.cpp:12: undefined reference to `Poco::UUID::UUID()'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe: *** [Debug/dll1.so] Error 1
dll1.mk:77: recipe for target `Debug/dll1.so' failed
1 errors, 0 warnings

最佳答案

您的成员函数 x::func1() 永远不会在该编译单元(源文件)中使用 ODR。大多数编译器只会为类定义内定义的成员函数生成编译代码,前提是该成员函数在正在编译的编译单元内ODR-used。假设其他一些源文件确实使用了 x::func1()。如果您编译该其他源文件,编译器将在与该其他源文件相对应的目标文件中为 x::func1() 生成目标代码。

编译器可以在此处绕过为 x::func1() 生成编译代码的过程,因为类定义必须在所有编译单元中相同。如果您编译其他一些具有不同类 x 定义的源文件,那么您就违反了单一定义规则。这是未定义的行为,不需要诊断。

如果没有源文件使用x::func1(),您就会有一些永远不会被编译的死代码。代码有错误,但从未检测到。

编译器无法绕过为自由函数 func1() 生成编译代码。该函数有外部联动;编译器无法判断它是否可以在其他地方使用。编译器必须为该自由函数生成编译代码。

这是一个最小的工作示例:

class Missing {
public:
   Missing();
   int value;
};

class UsesMissing {
public:

   int use_missing () {
      Missing missing;
      return missing.value;
   }

   int dont_use_missing () {
      return 0;
   }
};

#ifdef DEFINE_USE_MISSING
int use_missing () {
   Missing missing;
   return missing.value;
}
#endif

int main () {
   UsesMissing test;
#ifdef USE_MISSING
   return test.use_missing();
#else
   return test.dont_use_missing();
#endif
}

在未定义 DEFINE_USE_MISSINGUSE_MISSING 的情况下进行编译,这可以很好地编译和链接 g++ 和 clang++。定义这些标志之一,并且由于 undefined reference Missing::Missing(),文件在链接步骤中失败。

关于c++ - 在我的函数中使用简单类时出现 undefined reference 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18610206/

相关文章:

windows - 如何在 Windows 上将 clang 与 mingw-w64 header 一起使用

android - 如何从 Android Studio/gradle 中的构建中排除 C++ 代码目录?

c++ - 如何将公共(public)接口(interface)的子集暴露给类

c - 有没有办法在 Linux 上使用 GCC/Clang 强制多重定义的符号?

c++ - Lib 文件和定义

c++ - Eclipse C++ 未定义引用

c++ - 链接到 SFML 的 Unresolved external 错误(SFML 2.2,Visual Studio Community 2013)

c++ - 在 openCV 中为 oclMat 添加小图像到大图像

c++ - ostream 的问题

macos - 如何使用brew链接到新的gcc版本?