Ошибка отсутствия символов компилятора Solaris 5-10 CC вызывает сбой связи

Возможный дубликат:
Solaris 10 CC Ошибка препроцессора вызывает неопределенные символы

Прошу прощения, если этот вопрос покажется вам знакомым. Вчера я опубликовал эту проблему здесь: Ошибка препроцессора Solaris 10 CC вызывает неопределенные символы< /а>. Однако я добавил дополнительную уточняющую информацию (которую я узнал со вчерашнего дня), которая появляется только в этом посте.

У меня есть очень простой файл C++, который я компилирую на Solaris 5-10 с помощью компилятора CC. Вот исходный код в моем файле myTest.C:

#include <map>
std::map<int, bool> myVar2;
int main() { return 0; }

Я хотел бы сначала запустить препроцессор 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
57 direct_symbols.txt
45 indirect_symbols.txt

Удивительно, но объектный файл, скомпилированный напрямую, содержит 12 символов, которых нет в файле, скомпилированном косвенным образом. Почему? Это кажется мне серьезной ошибкой. Почему эти символы отсутствуют в косвенно скомпилированном файле? Если они не нужны, то почему они включены в непосредственно скомпилированный файл? Разве прямая компиляция не должна сначала выполнять ту же предварительную обработку и просто скрывать ее от пользователя? Что здесь происходит?

Вы можете видеть, что эти отсутствующие символы препятствуют окончательной компоновке косвенно скомпилированного объектного файла. Но напрямую скомпилированный объектный файл прекрасно линкуется:

% CC -o myFile_direct myFile_direct.o
% CC -o myFile_indirect myFile_indirect.o
Undefined                       first referenced
 symbol                             in file
main                                /opt/solstudio12.2/prod/lib/crt1.o
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> > >::__deallocate_buffers() myFile_indirect.o
__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,__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) myFile_indirect.o
ld: fatal: Symbol referencing errors. No output written to myFile_indirect

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:

person Saqib Ali    schedule 14.10.2012    source источник
comment
Что вы называете Solaris 5-10 (cat /etc/release)? Какую версию компилятора вы используете (CC -V)?   -  person jlliagre    schedule 14.10.2012
comment
Версия ОС: Oracle Solaris 10 9/10 s10s_u9wos_14a SPARC. Версия CC: Sun C++ 5.11 SunOS_sparc 2010/08/13   -  person Saqib Ali    schedule 14.10.2012


Ответы (1)


Вот что люди из службы поддержки Solaris рассказали мне об этой проблеме:

«Обходной путь для вашей проблемы заключается в том, чтобы не использовать любезный источник *.i (сгенерированный флагом компиляции C++ -P ), а вместо этого использовать первичный источник *.cpp для создания объектного модуля *.o.

Неудивительно, что в этой области могут быть скрытые дефекты, потому что флаг компиляции C++ -P для создания бесплатного источника был в первую очередь предназначен для информации и диагностики расширения включаемого файла».

Фу. Это действительно ужасно.

person Saqib Ali    schedule 15.10.2012