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-8.5.0/gcc/Interoperation.html