【问题标题】:Solaris 10 CC Preprocessor bug causes undefined symbolsSolaris 10 CC 预处理器错误导致未定义符号
【发布时间】:2012-10-03 21:59:11
【问题描述】:

我有一个非常简单的 C++ 文件,如下所示,我正在使用 CC 编译器在 Solaris 5-10 上进行编译。这是我的文件 myTest.C 中的源代码:

#include <map>
std::map<int, bool> myVar2;

我想首先在这个文件上运行 CC 预处理器,检查预处理文件,然后将该预处理文件编译成目标文件。我称之为“间接编译”。为此,我执行以下操作:

% CC -P -o myFile_indirect.i myFile.C
% CC -c -o myFile_indirect.o myFile_indirect.i

我还想编译这个文件,而不像通常那样进行单独的预处理步骤。我称之为“直接编译”。为此,我执行以下操作:

% CC -c -o myFile_direct.o myFile.C

理论上,myFile_direct.o 和 myFile_indirect.o 在功能上应该是等效的。它们当然应该在各自的符号表中包含相同数量的符号,对吧?那么让我们来看看它们的符号:

% gnm myFile_direct.o | c++filt > direct_symbols.txt
% gnm myFile_indirect.o | c++filt > indirect_symbols.txt
% wc -l *direct_symbols.txt
55 direct_symbols.txt
43 indirect_symbols.txt

令人震惊的是,直接编译的目标文件包含 12 个在间接编译的文件中不存在的符号。为什么?这对我来说似乎是一个严重的错误。为什么间接编译的文件中没有这些符号?如果它们是不必要的,为什么将它们包含在直接编译的文件中?直接编译不应该先做同样的预处理,然后对用户隐藏它吗?这是怎么回事?

PS。我不认识额外的十二个符号,也不明白它们的目的是什么:

00000010 T __rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__rb_tree_node*__rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__nil()
00000010 T __rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::iterator __rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::erase(__rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::iterator)
00000010 T void __rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__erase(__rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__rb_tree_node*)
00000010 T __rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__rb_tree_node*&__rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__right(__rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__rb_tree_node*)
00000010 T __rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::iterator&__rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::iterator::operator++()
00000010 T __rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__rb_tree_node*__rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__maximum(__rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__rb_tree_node*)
00000010 T __rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__rb_tree_node*__rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__minimum(__rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__rb_tree_node*)
00000010 T __rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__rb_tree_node*&__rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__leftmost()
00000010 T __rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__rb_tree_node*&__rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__rightmost()
00000010 T void __rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__erase_leaf(__rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__rb_tree_node*)
00000010 T void __rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__rotate_left(__rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__rb_tree_node*)
00000010 T void __rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__rotate_right(__rwstd::__rb_tree<int,std::pair<const int,bool>,__rwstd::__select1st<std::pair<const int,bool>,int>,std::less<int>,std::allocator<std::pair<const int,bool> > >::__rb_tree_node*)

【问题讨论】:

  • 额外的符号来自 std::map 类使用的内部类。如果您检查 标头,您将能够自己看到这一点。就我个人而言,我不认为您发现了什么是错误,我也不真正理解您为什么如此关注它。只要最终的程序是等价的,我不在乎目标文件中的内容。
  • 你是对的。只要最终的程序是等价的,我不在乎目标文件中有什么。但它们会等价吗?我担心他们不会。如果它们会是,那么我没有什么可担心的——但是这意味着这些符号是无关的/冗余的。
  • 但最终的程序并不等价。实际上,我什至无法构建我的最终程序,因为链接器抱怨这些丢失的符号。
  • 使用直接方法或间接方法构建时出现链接器错误?

标签: c++ compiler-construction solaris cc


【解决方案1】:

尝试使用CC -E 代替CC -P。当我这样做时,nm(1) 列表是相同的,并且目标文件仅相差几个字节(鉴于我可以在 *.o 中看到 *.c*.i 文件的名称,这种差异并不奇怪)。

手册页并没有真正解释这两个标志之间的区别,但确实强调了 -E 的 C++,所以我想知道 -P 是否只打算成为 C。

如果您想弄清楚直接方法的真正含义,那么这可能会很有启发性:

truss -f -a -texec CC myFile.C

直接编译方法不调用CC -PCC -E,而是调用带有大量标志的ccfe(然后是fbe,然后是ld...)。

【讨论】:

    猜你喜欢
    • 2012-10-04
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    • 2012-02-19
    • 2014-03-27
    • 2013-08-26
    • 1970-01-01
    • 2023-04-04
    相关资源
    最近更新 更多