Solaris 10 CC预处理器错误导致未定义的符号

Solaris 10 CC Preprocessor bug causes undefined symbols

本文关键字:未定义 符号 错误 CC 预处理 处理器 Solaris      更新时间:2023-10-16

我有一个非常非常简单的C++文件,如下所示,我正在Solaris 5-10上使用CC编译器进行编译。这是我的文件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*)

尝试使用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…)