Spec-Zone.ru › GCC 13

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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API