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

Совместимость с С++ 11 назад

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

Пример для ясности:

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

Я еще не тестировал свою теорию, потому что у меня нет доступа к компилятору, совместимому с С++ 11, и мои поисковые запросы не помогли.

4b9b3361

Ответ 1

Вы правы. Сам код компилируется для работы на любой платформе с помощью компилятора С++. Новые языковые конструкции (ranged for, новые ключевые слова, такие как auto и т.д.), Компилируются с новым компилятором, чтобы отлично работать в старых системах.

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

Предполагая, что ваш код использует новые символы:

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

Ответ 2

Стандарт не дает никаких гарантий относительно того, что работает с более ранними версиями. Спецификация определяет требования к реализации, а реализация либо соответствует этим требованиям, либо нет. Объединение частей реализации С++ 11 с частями более ранней реализации не переносимо, и вряд ли это практически возможно.

Возможно даже, что запись программы, которая вообще не использует стандартную библиотеку и которая не использует никаких функций С++ 11, не будет совместима с ABI с двоичными файлами из реализации С++ 03. Например, разработчик может потенциально воспользоваться новой версией для изменения соглашений о вызовах. Таким образом, вообще ограничение программы на такие функции, как auto и range-for, не обязательно будет совместимым с ABI.

Как я могу определить, какие части С++ 11 являются частью libstdС++, и что фактически скомпилируется в двоичный файл?

Даже если вы не используете какую-либо часть стандартной библиотеки (вы можете гарантировать это, просто не используя заголовки), это не гарантирует, что скомпилированный двоичный файл не требует поддержки во время выполнения, предоставляемой реализацией С++ 11, Парой примеров языковых функций, которые могут полагаться на поддержку во время выполнения, являются исключения и виртуальные члены.

И снова поддержка библиотеки времени выполнения - это не единственная вещь, которая может быть несовместимой с ABI между С++ 03 и С++ 11.

C++ 11 нарушает соответствие ABI старым библиотекам?

Нет, я не думаю, что спецификация требует чего-то, что препятствует реализации С++ 03 и С++ 11 совместного использования ABI. Однако то, что вы хотите знать, являются более старыми спецификациями, достаточно строгими, что более старые реализации должны иметь ABI, которые потенциально могут быть использованы при реализации С++ 11? Ответ там не так, и, таким образом, разработчик может быть вынужден нарушить совместимость с ABI при реализации С++ 11.


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

Другой вариант заключается в том, что вместо того, чтобы пытаться смешивать реализации С++ 11 и С++ 03, ваша реализация С++ 11 может создавать автономные двоичные файлы (или, в основном, автономные, по крайней мере, ему придется полагаться на системный вызов операционной системы ABI), который не требует внешней поддержки во время выполнения.

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