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