13.2 Взаимодействие
В данном разделе перечислены различные трудности, возникающие при использовании GCC совместно с другими компиляторами или с ассемблерами, линковщиками, библиотеками и отладчиками на определенных системах.
- На многих платформах GCC поддерживает другой ABI для C++ по сравнению с другими компиляторами, поэтому объектные файлы, скомпилированные GCC, не могут использоваться с объектными файлами, сгенерированными другим компилятором C++.
Область, где разница наиболее заметна, — это преобразование имен. Использование различного преобразования имен является намеренным, чтобы защитить вас от более скрытых проблем. Компиляторы отличаются по многим внутренним деталям реализации C++, включая: как размещаются экземпляры классов, как реализована множественная наследование и как обрабатываются виртуальные вызовы функций. Если бы кодировка имен была одинаковой, ваши программы связывались бы с библиотеками, предоставленными другими компиляторами, но при запуске программы аварийно завершались бы. Несовместимые библиотеки затем обнаруживаются во время линковки, а не во время выполнения.
- На некоторых системах BSD, включая некоторые версии Ultrix, использование профилирования приводит к тому, что деструкторы статических переменных (в настоящее время используются только в C++) не выполняются.
- На SPARC GCC выравнивает все значения типа
doubleна границе 8 байт, и ожидает, что каждыйdoubleтакже будет выровнен таким образом. Компилятор Sun обычно обеспечиваетdoubleзначения с выравниванием 8 байт, за одним исключением: аргументы функций типаdoubleмогут не быть выровнены.В результате, если функция, скомпилированная Sun CC, получает адрес аргумента типа
doubleи передает этот указатель типаdouble *функции, скомпилированной GCC, обращение по указателю может вызвать фатальный сигнал.Один из способов решения этой проблемы — компилировать всю программу с помощью GCC. Другое решение — изменить функцию, которая компилируется с Sun CC, чтобы скопировать аргумент в локальную переменную; локальные переменные всегда правильно выравниваются. Третье решение — изменить функцию, которая использует указатель, чтобы обратиться к нему через следующую функцию
access_doubleвместо прямого использования ‘*’:inline double access_double (double *unaligned_ptr) { union d2i { double d; int i[2]; }; union d2i *p = (union d2i *) unaligned_ptr; union d2i u; u.i[0] = p->i[0]; u.i[1] = p->i[1]; return u.d; }Запись в указатель может быть выполнена аналогичным образом с помощью того же объединения.
- В Solaris функция
mallocв библиотеке libmalloc.a может выделять память, которая выровнена только по 4 байтам. Поскольку GCC на SPARC предполагает, что типы данных double выровнены по 8 байтам, это может привести к фатальному сигналу, если значения double хранятся в памяти, выделенной библиотекой libmalloc.a.Решение — не использовать библиотеку libmalloc.a. Используйте вместо неё
mallocи аналогичные функции из libc.a; у них нет этой проблемы. - На машине HP PA ADB иногда не работает с функциями, скомпилированными с помощью GCC. В частности, он не работает с функциями, использующими
allocaили массивы переменного размера. Это связано с тем, что GCC не генерирует описатели разветвления HP-UX для таких функций. Их даже может быть невозможно сгенерировать. - Отладка (-g) не поддерживается на машине HP PA, если вы не используете предварительные инструменты GNU.
- Взятие адреса метки может генерировать ошибки от ассемблера HP-UX PA. GAS для PA не имеет этой проблемы.
- Использование параметров с плавающей точкой для косвенных вызовов статических функций не будет работать при использовании ассемблера HP. Просто нет способа для GCC указать, какие регистры содержат аргументы для статических функций при использовании ассемблера HP. GAS для PA не имеет этой проблемы.
- В чрезвычайно редких случаях, связанных с очень большими функциями, вы можете получить ошибки от HP линковщика, жалующиеся на смещение безусловного разветвления за пределами границ. Это раньше происходило чаще в предыдущих версиях GCC, но сейчас встречается исключительно редко. Если вы столкнетесь с этим, вы можете обойти проблему, сделав вашу функцию меньше.
- Код, скомпилированный GCC, иногда генерирует предупреждения от ассемблера HP-UX следующего вида:
(warning) Use of GR3 when frame >= 8192 may cause conflict.
Эти предупреждения безопасны и могут быть проигнорированы.
- В крайне редких случаях, связанных с очень большими функциями, вы можете получить ошибки от AIX ассемблера, жалующиеся на слишком большой смещение. Если вы столкнетесь с этим, вы можете обойти проблему, сделав свою функцию меньше.
- Библиотека libstdc++.a в GCC полагается на семантику динамического линковщика SVR4, которая объединяет глобальные символы между библиотеками и приложениями, что особенно необходимо для функциональности потоков C++. Это не является стандартным поведением AIX общих библиотек и динамической линковки. libstdc++.a построена на AIX с включенной «линковкой во время выполнения», чтобы объединение символов могло произойти. Для использования этой функции приложение, связанное с libstdc++.a, должно включать флаг -Wl,-brtl в строке линковки. G++ не может навязать это, потому что этот параметр может повлиять на семантику программы пользователя, и пользователи могут не всегда использовать ‘g++’ для линковки своего приложения. Приложения не обязаны использовать флаг -Wl,-brtl в строке линковки — остальная часть библиотеки libstdc++.a, которая не зависит от семантики объединения символов, будет продолжать работать правильно.
- Приложение может вставить собственное определение функций для функций, вызываемых libstdc++.a с «линковкой во время выполнения», включенной в AIX. Для этого приложение должно быть связано с опцией «линковки во время выполнения», и функции явно должны быть экспортированы приложением (-Wl,-brtl,-bE:exportfile).
- AIX на RS/6000 поддерживает (NLS) среды за пределами США. Компиляторы и ассемблеры используют NLS для поддержки представлений локали-специфичных объектов, включая числа с плавающей точкой (‘.’ против ‘,’ для разделения десятичных дробей). Были сообщения о проблемах, когда библиотека, связанная с GCC, не производит те же форматы чисел с плавающей точкой, которые принимает ассемблер. Если у вас возникла эта проблема, установите переменную окружения
LANGв ‘C’ или ‘En_US’. - Даже если вы укажете -fdollars-in-identifiers, вы не сможете успешно использовать ‘$’ в идентификаторах на RS/6000 из-за ограничения в IBM ассемблере. GAS поддерживает эти идентификаторы.
Далее: Несовместимости, Предыдущее: Действительные ошибки, Наверх: Проблемы [Оглавление][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-7.5.0/gcc/Interoperation.html