9 Двоичная совместимость ¶
Двоичная совместимость охватывает несколько взаимосвязанных понятий:
- интерфейс двоичных приложений (ABI)
-
Набор соглашений выполнения, используемых всеми инструментами, которые работают с двоичными представлениями программы, включая компиляторы, ассемблеры, компоновщики и поддержку языка выполнения. Некоторые ABI являются формальными, с письменным описанием, возможно, разработанным несколькими заинтересованными сторонами. Другие — просто то, как на самом деле работают определённый набор инструментов.
- соответствие ABI
-
Компилятор соответствует ABI, если он генерирует код, который следует всем спецификациям, перечисленным в этом ABI. Библиотека соответствует ABI, если она реализована в соответствии с этим ABI. Приложение соответствует ABI, если оно построено с использованием инструментов, соответствующих ABI, и не содержит исходного кода, который специально изменяет поведение, заданное ABI.
- конвенции вызова
-
Конвенции вызова — подмножество ABI, которые определяют, как передаются аргументы и возвращаются результаты функции.
- взаимодействие
-
Разные наборы инструментов взаимодействуют, если они генерируют файлы, которые могут использоваться в одной программе. Набор инструментов включает компиляторы, ассемблеры, компоновщики, библиотеки, заголовочные файлы, файлы запуска и отладчики. Двоичные файлы, созданные разными наборами инструментов, не взаимодействуют, если они не реализуют один и тот же ABI. Это относится как к разным версиям одних и тех же инструментов, так и к инструментам разных поставщиков.
- взаимовызываемость
-
Возможность функции в двоичном файле, созданном одним набором инструментов, вызывать функцию в двоичном файле, созданном другим набором инструментов, является подмножеством взаимодействия.
- функции, определяемые реализацией
-
Стандарты языка включают списки функций, определяемых реализацией, поведение которых может отличаться от одной реализации к другой. Некоторые из этих функций обычно покрываются ABI платформы, а другие нет. Функции, которые не покрываются ABI, обычно влияют на то, как ведёт себя программа, но не на взаимовызываемость.
- совместимость
Соответствие одному и тому же ABI и одинаковому поведению функций, определяемых реализацией, имеют отношение к совместимости.
Интерфейс двоичных приложений, реализованный компилятором C или C++, влияет на генерацию кода и поддержку выполнения для:
- размера и выравнивания типов данных
- размещения структурированных типов
- конвенций вызова
- конвенций использования регистров
- интерфейсов для поддержки выполнения арифметических операций
- форматов файлов объектов
Кроме того, интерфейс двоичных приложений, реализованный компилятором C++, влияет на генерацию кода и поддержку выполнения для:
- искажения имён
- обработки исключений
- вызова конструкторов и деструкторов
- размещения, выравнивания и заполнения классов
- размещения и выравнивания виртуальных таблиц
Некоторые параметры компиляции GCC заставляют компилятор генерировать код, который не соответствует умолчанию ABI платформы. Другие параметры приводят к различному поведению программы для функций, определяемых реализацией, которые не покрываются ABI. Эти параметры предоставляются для согласованности с другими компиляторами, которые не следуют умолчанию ABI платформы или обычному поведению функций, определяемых реализацией, для платформы. Будьте очень осторожны при использовании таких параметров.
Большинство платформ имеют хорошо определённый ABI, который покрывает код C, но ABI, которые покрывают функциональность C++, пока не являются распространёнными.
Начиная с GCC 3.2, двоичные соглашения GCC для C++ основаны на написанном, независимом от поставщика C++ ABI, который был разработан для конкретного 64-битного Itanium, но также включает общие спецификации, применимые к любой платформе. Этот C++ ABI также реализуется другими поставщиками компиляторов на некоторых платформах, особенно системах GNU/Linux и BSD. Мы старались обеспечить стабильный ABI, совместимый с будущими выпусками GCC, но есть вероятность столкнуться с проблемами, которые затруднят это. Такие проблемы могут включать разные интерпретации C++ ABI разными поставщиками, ошибки в ABI или ошибки в реализации ABI в разных компиляторах. Переключатель -Wabi в GCC предупреждает, когда G++ генерирует код, который, вероятно, не совместим с C++ ABI.
Библиотека C++, используемая с компилятором C++, включает стандартную библиотеку C++, с функциональностью, определённой в стандарте C++, плюс поддержку языка выполнения. Поддержка выполнения включена в C++ ABI, но для стандартной библиотеки C++ формального ABI нет. Две реализации этой библиотеки совместимы, если одна следует фактическому ABI другой и если обе построены одним компилятором или компиляторами, которые соответствуют одному ABI для компилятора C++ и поддержки выполнения.
Когда G++ и другой компилятор C++ соответствуют одному C++ ABI, но реализации стандартной библиотеки C++, которые они обычно используют, не следуют одному ABI для стандартной библиотеки C++, файлы объектов, созданные этими компиляторами, могут быть использованы в одной программе только в том случае, если они используют одну и ту же библиотеку C++. Это требует указания расположения заголовочных файлов библиотеки C++ при вызове компилятора, чья обычная библиотека не используется. Расположение заголовочных файлов GCC для C++ зависит от того, как был сконфигурирован сборка GCC, но можно увидеть, используя параметр G++ -v. При параметрах конфигурации по умолчанию для G++ 3.3 в строке компиляции для другого компилятора C++ необходимо указать
-Igcc_install_directory/include/c++/3.3
Аналогично, компиляция кода с G++, который должен использовать библиотеку C++ отличную от GNU C++ библиотеки, требует указания местоположения заголовочных файлов этой другой библиотеки.
Самый простой способ связать программу с использованием конкретной библиотеки C++ — использовать драйвер C++, который по умолчанию указывает на эту библиотеку C++. Например, драйвер g++ указывает компоновщику местоположение библиотеки C++ GCC (libstdc++) плюс другие необходимые библиотеки и файлы запуска в правильном порядке.
Если программе необходимо использовать другую библиотеку C++ и нет возможности выполнить окончательную компоновку с помощью драйвера C++, который по умолчанию использует эту библиотеку, необходимо указать g++ местоположение и имя этой библиотеки. Возможно, также потребуется указать разные файлы запуска и другие библиотеки поддержки выполнения, а также подавить использование поддерживающих библиотек GCC с помощью одного или нескольких параметров -nostdlib, -nostartfiles и -nodefaultlibs.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-10.5.0/gcc/Compatibility.html