gcc — Можете ли вы смешивать c ++, скомпилированные с разными версиями одного и того же компилятора

Например, могу ли я смешать набор библиотек, которые были скомпилированы, скажем, в GCC-4.6 с GCC-4.9.

Я знаю, что разные «породы» компиляторов, такие как VS, не могут быть с MinGW, но могут ли разные поколения одного и того же компилятора? Возможны ли проблемы? Если да, то?

22

Решение

Иногда разные поколения одного и того же компилятора Можно быть совместимыми друг с другом, но не всегда. Например, GCC 4.7.0 изменил свой C / C ++ ABI, это означает, что библиотеки, скомпилированные с 4.7.0+ и 4.7.0-, вряд ли будут совместимы друг с другом (поэтому в вашем примере библиотека, скомпилированная с 4.6, будет не быть совместимым с библиотекой, скомпилированной с 4.9). Также могут быть ошибки ABI в данном выпуске компилятора, как это произошло в GCC 4.7.0 / 4.7.1:

В версиях 4.7.0 и 4.7.1 GCC были внесены изменения в стандартную библиотеку C ++, которые повлияли на ABI в режиме C ++ 11: в std :: list был добавлен элемент данных, изменив его размер и изменив определения некоторых функций-членов, и Конструктор перемещения std :: pair был нетривиальным, что изменило соглашение о вызовах для функций с аргументами std :: pair или возвращаемыми типами. Несовместимости ABI были исправлены для GCC версии 4.7.2, но в результате код C ++ 11, скомпилированный с GCC 4.7.0 или 4.7.1, может быть несовместим с кодом C ++ 11, скомпилированным с различными версиями GCC и с C ++ 98 / C ++ 03 код, скомпилированный с любой версией.

Страница GCC ABI Policy and Guidelines. указывает, что они пытаются поддерживать прямую совместимость, но не обратную совместимость:

Управление версиями дает возможность последующим выпускам двоичных файлов библиотеки добавлять новые символы и добавлять функциональность, сохраняя при этом совместимость с предыдущими выпусками серии. Таким образом, двоичные файлы программы, связанные с первоначальным выпуском двоичного файла библиотеки, будут по-прежнему работать правильно, если двоичный файл библиотеки будет заменен последующими двоичными файлами библиотеки, которые тщательно управляются. Это называется прямой совместимостью.

Обратное (обратная совместимость) не соответствует действительности. Невозможно взять двоичные файлы программы, связанные с последней версией двоичного файла библиотеки в серии выпусков (с добавленными дополнительными символами), заменить начальный выпуск двоичного файла библиотеки и оставаться совместимым с линком.

На этой странице также есть довольно длинные пояснения по системе управления версиями, которые GCC использует для маркировки различных версий заданных компонентов, а также пояснения по управлению версиями самого GCC:

Разрешенные изменения

  • Следующее приведёт к увеличению младшего номера версии библиотеки, скажем, от «libstdc ++. So.3.0.4» до «libstdc ++. So.3.0.5».

  • Добавление экспортированного глобального или статического члена данных

  • Добавление экспортируемой функции, статической или не виртуальной функции-члена

  • Добавление экспортированного символа или символов дополнительными экземплярами

  • Возможны другие допустимые изменения.

Запрещенные изменения

Следующий неполный список приведет к увеличению номера основной версии библиотеки, скажем, с «libstdc ++. So.3.0.4» до «libstdc ++. So.4.0.0».

  • Изменения в компиляторе gcc / g ++ ABI

  • Изменение размера экспортируемого символа

  • Изменение выравнивания экспортируемого символа

  • Изменение макета экспортируемого символа

  • Изменение искажения на экспортированном символе

  • Удаление экспортированного символа

  • Изменение свойств наследования типа путем добавления или удаления базовых классов

  • Изменение размера, выравнивания или расположения типов, указанных в стандарте C ++. Они не обязательно могут быть созданы или иным образом экспортированы в двоичный файл библиотеки и включают в себя все необходимые аспекты локали, а также такие вещи, как std :: basic_streambuf, et al.

  • Добавление явного конструктора или деструктора копирования в класс, который в противном случае имел бы неявные версии. Это изменит способ работы компилятора с этим классом в выражениях или параметрах возврата по значению: вместо передачи экземпляров этого класса в регистрах компилятор будет вынужден использовать память. Дополнительную информацию смотрите в разделе «Соглашения о вызовах функций и API» документации C ++ ABI.

Обратите внимание на жирный бит. В идеальном мире версии GCC с тем же номером основного выпуска были бы двоично-совместимыми. Это не идеальный мир, поэтому тестируйте его очень внимательно, прежде чем смешивать версии компилятора, как это, но в целом вы, вероятно, будете в порядке.

21

Другие решения

Вы можете смешивать сгенерированные двоичные файлы из разных компиляторов или разных версий одного и того же компилятора, если они совместимы с ABI (Application Binary Interface).

Вещи как:

  • Процедура вызова
  • Имя искажения
  • Обработка локального хранилища потоков

все являются частью ABI.

Если что-то из этого изменится, вы обнаружите, что либо получаете ошибки компоновщика, либо происходит сбой, либо другие формы непредвиденного поведения.
Как правило, поставщики компиляторов часто пытаются поддерживать хотя бы обратную совместимость со старой версией, но это не гарантируется. Как уже говорили другие, вы должны либо прочитать документацию, либо просто перекомпилировать все.

3

По вопросам рекламы [email protected]