Spec-Zone.ru › GCC 9

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

Spec-Zone.ru

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