14.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 с включённой «runtime-линковкой», чтобы обеспечить объединение символов. Для использования этой функции приложение, связанное с libstdc++.a, должно включить флаг -Wl,-brtl в строке линковки. G++ не может навязать это, так как этот параметр может повлиять на семантику программы пользователя, и пользователи не всегда используют ‘g++’ для линковки своего приложения. Приложения не обязаны использовать флаг -Wl,-brtl в строке линковки — остальная часть библиотеки libstdc++.a, которая не зависит от семантики объединения символов, будет продолжать работать правильно.
- Приложение может вставить собственное определение функций для функций, вызываемых libstdc++.a с включённой «runtime-линковкой» на AIX. Для этого приложение должно быть связано с опцией «runtime-линковки», и функции должны быть явно экспортированы приложением (-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-12.2.0/gcc/Interoperation.html