是否有解决未定义参考/未解决符号问题的一般准则?

时间:2009-01-29 14:45:00

标签: c++ reference undefined symbols

我有几个“未定义的引用”(在链接期间)和“未解析的符号”(在dlopen之后的运行时)我工作的地方。它是一个相当大的makefile系统。

是否存在链接库和使用编译器标志/选项来规避这些类型错误的一般规则和指南?

2 个答案:

答案 0 :(得分:6)

如果您使用的是MSVC:

您无法通过设置标志来规避此类错误:这意味着某些单位(.cpp)不具有已声明标识符的定义。它肯定是由某个地方缺少包含或缺少对象定义(通常是静态对象)引起的。

在开发过程中,您可以遵循这些准则(来自those articles),以确保您的所有cpp包含他们需要的所有标题但不再包含:

  
      
  • 每个cpp文件首先包含自己的头文件。这是最多的   重要指南;其他一切   从这里开始。唯一的例外   此规则是预编译头   包含在Visual Studio中;那些   总是必须是第一个包括在内   文件。有关预编译的更多信息   本文第二部分的标题。
  •   
  • 头文件必须包含解析它所需的所有头文件。   这与第一个相辅相成   指南。我知道有些人会尝试   从不包含头文件   头文件声称效率或   这些方面的东西。然而,   如果必须在a之前包含文件   头文件可以解析,它必须   被包括在某处。优势   将其直接包含在标题中   文件是我们可以随时决定的   拉入我们感兴趣的头文件   在,我们保证它会   按原样工作。我们没有必要玩   “猜猜你需要的其他标题”   游戏。
  •   
  • 头文件应该具有最少数量的头文件   需要解析它。以前的   规则说你应该拥有所有的   在头文件中包含您需要的内容。   这条规则说你不应该有   比你更多。显然,开始   通过删除(或不添加   第一名)无用包括   声明。然后,使用尽可能多的前进   声明,你可以代替   包括。如果你拥有的只是   你是一个类的引用或指针   不需要包括那个类'   头文件;前瞻性参考将   做得好,效率更高。
  •   

但是正如评论者的建议,似乎你正在使用g ++ ......

答案 1 :(得分:5)

设置一个构建系统,其中X依赖于Y,这取决于Z有用。当你进入圈子(Z依赖于X)时,事情变得丑陋。

通常,订单库被链接(“-lZ -lY -lX”vs“-lX -lY -lZ”)导致悲伤。更少见的是,您在搜索路径上的多个位置具有相同的库名称,或者您对尚未重新编译的过期版本具有相同的链接。

“nm --demangle” 可以让您了解内容的定义/使用位置。

“ldd” 可用于查看您所依赖的动态库。

gcc / g ++标志 -print-file-name = LIBRARY 可以帮助确切地追踪正在使用的库。


事后补充:(因为你询问规则/指导方针。)

可以设置一个makefile系统:

  • 如果module = D取决于模块A,B和& C。
  • 然后尝试使模块= D首先制作模块A,B和C。
  • 更重要的是,module = D将自动确定其库(-lA等),库路径(-LA)以及来自模块A,B和C的makefile的包含路径(-IA)。

这可能会有点毛茸茸的设置。上次我这样做时,我倾向于仅缓存信息而不是分支过多的make子进程。加上makefile-imports和一个小的perl脚本来删除重复项。 Kludgey,我知道。 (不想在基础设施上花费时间的权力。)但是可以做到。

然后,我再次使用GNU-make,它有一些扩展名。