Solaris 10 CC预处理器错误导致未定义的符号 [英] Solaris 10 CC Preprocessor bug causes undefined symbols
问题描述
我有一个非常非常简单的C ++文件,如下所示,我在使用CC编译器在Solaris 5-10上编译。这是我的文件myTest.C中的源代码:
I have a very very simple C++ file as follows that I'm compiling on Solaris 5-10 with the CC compiler. Here is the source code in my file myTest.C:
#include <map>
std::map<int, bool> myVar2;
我想首先在此文件上运行CC预处理器,检查预处理文件,然后将该预处理文件编译成一个目标文件。我称之为间接编译。为此,我执行以下操作:
I would like to first run the CC pre-processor on this file, examine the pre-processed file, and then compile that pre-processed file into an object file. I call this "indirect-compiling". To do this, I do the following:
% CC -P -o myFile_indirect.i myFile.C
% CC -c -o myFile_indirect.o myFile_indirect.i
我也想编译这个文件,单独的预处理步骤。我称之为直接编译。为此,我执行以下操作:
I would also like to compile this file without a separate pre-processing step as is normally done. I call this "direct-compiling". To do this, I do the following:
% CC -c -o myFile_direct.o myFile.C
理论上,myFile_direct.o和myFile_indirect.o应该在功能上是等价的。它们应该在其各自的符号表中包含相同数量的符号吗?因此,让我们检查他们的符号:
In theory, myFile_direct.o and myFile_indirect.o should be functionally equivalent. They should certainly contain the same number of symbols in their respective symbol tables right? So let's examine their symbols:
% 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个符号。为什么?这似乎是一个严重的bug给我。为什么这些符号不存在于间接编译文件中?如果它们是不必要的,为什么它们包括在直接编译的文件中?不是直接编译应该先做相同的预处理,只是隐藏它从用户?这是怎么回事?
Shockingly, the directly-compiled object file contains 12 symbols that are absent from the indirectly compiled file. Why? This seems like a serious bug to me. Why are these symbols absent from the indirectly compiled file? If they are unnecessary, why are they included in the directly compiled file? Isn't direct-compilation supposed to do the same pre-processing first and just hide it from the user? What is going on here?
PS。我不认识这十二个额外的符号,我也不明白它们的目的是什么:
PS. I don't recognize the twelve extra symbols nor do I understand what their purpose is:
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)
列表是相同的,目标文件只有几个字节不同(假设我可以看到<$ c $在 *。o
中的 *。i
Try using CC -E
in place of CC -P
. When I do this thenm(1)
listings are the same and the object files only differ by a few bytes (given that I can see the names of the *.c
and *.i
files in the *.o
this difference is not surprising).
手册页并没有真正解释这两个标志之间的区别,但强调C ++为 -E
所以我不知道 -P
是否只是C。
The man page doesn't really explain the difference between the two flags but does stress C++ for -E
so I wonder if -P
was intended to be C only.
要解决直接方法真正需要什么,那么这可能证明启发:
If you're trying to work out what the direct method really entails, then this might prove enlightening:
truss -f -a -texec CC myFile.C
直接编译方法不会调用 CC -P
或 CC -E
,而是使用一整排标志(然后<$ c)调用 ccfe
$ c> fbe 然后 ld
...)。
The direct compilation method doesn't call CC -P
or CC -E
but instead invokes ccfe
with a whole raft of flags (and then fbe
then ld
...).
这篇关于Solaris 10 CC预处理器错误导致未定义的符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!