Spec-Zone.ru › GCC 6

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 с включённой «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-6.5.0/gcc/Interoperation.html

Spec-Zone.ru

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