Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

Различные поколения одного и того же компилятора иногда могут быть совместимы друг с другом, но не всегда. Например, GCC 4.7.0 изменил свой 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 были внесены изменения в стандартную библиотеку С++, которая повлияла на работу ABI в режиме С++ 11: элемент данных был добавлен в std:: list, изменяя его размер и изменяя определения некоторого члена функции и конструктор std:: pair move был нетривиальным, что изменило вызывающее соглашение для функций с аргументами std:: pair или возвращаемыми типами. Несовместимость ABI была исправлена ​​для версии GCC версии 4.7.2, но в результате код С++ 11, скомпилированный с GCC 4.7.0 или 4.7.1, может быть несовместим с кодом С++ 11, скомпилированным с разными версиями GCC и с С++ 98/С++ 03, скомпилированный с любой версией.

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

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

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

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

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

  • Ниже будет увеличен номер версии младшей версии библиотеки, например, с "libstdС++. so.3.0.4" до "libstdС++. so.3.0.5".

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

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

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

  • Возможны и другие разрешенные изменения.

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

Следующий неисчерпывающий список приведет к увеличению размера основной версии библиотеки, скажем, от "libstdС++. so.3.0.4" до "libstdС++. so.4.0.0".

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

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

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

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

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

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

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

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

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

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

Ответ 2

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

Вещи вроде:

  • Процедура вызова
  • Название mangling
  • Потоковая локальная обработка данных

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

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