Разве обновления Visual Studio 2012 нарушают C ++ ABI?

Когда Microsoft впервые выпустила Visual Studio 2012 в сентябре 2012 года, они объявили о своем плане предоставления обновлений для Visual Studio на более регулярной основе. С тех пор они выпустили Visual Studio 2012, обновление 1 (Visual Studio 2012.1) в ноябре 2012 года и Visual Studio 2012, обновление 2 (Visual Studio 2012.2) в апреле 2013 г.

У меня вопрос: внесены ли в обновление какие-либо изменения в C ++ ABI (относительно начальной версии VS2012)? Безопасно ли связывать .libс разных версий VS2012?

Я искал в Интернете некоторое время и не мог найти какое-либо определенное заявление от Microsoft. Немного источники упомянуть, что некоторые ошибки в генерации кода C ++ были исправлены, но я полагаю, что это не означает изменение ABI?

18

Решение

Стефан Т. Лававей, ключевой автор реализации STL в Visual C ++, изложил правила в этом Реддит нить:

Вот точные правила:

Если вы включаете какие-либо заголовки стандартной библиотеки C ++, вы должны играть по ее правилам, и мы намеренно нарушаем двоичную совместимость между основными версиями (но сохраняем ее между исправлениями и пакетами обновлений). Любые изменения представления (включая, но не ограничиваясь добавлением / удалением членов данных) нарушают двоичную совместимость, поэтому это всегда происходит и почему мы ревностно защищаем это право.

[Надрез]

Итак, если вы играете по правилам STL, вам необходимо убедиться в следующем:

  • Все объектные файлы и статические библиотеки, связанные в один двоичный файл (EXE / DLL), должны быть скомпилированы с одной и той же основной версией. Мы добавили проверки компоновщика, чтобы несовпадение основных версий VS 2010+ приводило к серьезным ошибкам во время соединения, но если речь идет о VS 2008 или более ранней версии, мы не можем вам помочь (без машин времени). Поскольку здесь применяется ODR, вам действительно следует использовать один и тот же набор инструментов (то есть один и тот же уровень пакета обновления) для всех объектных файлов и статических библиотек. Например, мы исправили утечку памяти std :: string между VS 2010 RTM и SP1, но если вы смешаете RTM и SP1, полученная двоичная версия может или не может быть затронута утечкой. (Кроме того, вам нужно использовать те же настройки _ITERATOR_DEBUG_LEVEL и release / debug; сейчас у нас есть проверка компоновщика.)
  • Если у вас есть несколько двоичных файлов, загруженных в один и тот же процесс, и они передают объекты стандартной библиотеки C ++ друг другу, эти двоичные файлы должны быть собраны с одной и той же основной версией и параметрами _ITERATOR_DEBUG_LEVEL (выпуск / отладка тоже должны совпадать, я забыл, если вы можете уйти с несоответствием здесь). Важно отметить, что мы не можем обнаружить нарушения этого правила, поэтому вы должны следовать ему.
  • Несколько бинарных файлов, чьи интерфейсы являются чисто C или COM (или теперь WinRT), могут внутренне использовать разные основные версии, потому что эти вещи гарантируют двоичную совместимость. Если в ваших интерфейсах используется базовый язык C ++ (например, виртуальные), но вы крайне осторожны, чтобы никогда не упоминать какие-либо типы стандартной библиотеки C ++, тогда вы, вероятно, в порядке — компилятор действительно пытается избежать нарушения бинарной совместимости.

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

Итог — если вы компилируете все на 100% последовательно, вам не нужно беспокоиться ни о чем из этого. Не играйте в смешанные игры, если вы можете избежать этого.

13

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

Наконец, я нашел ответ на свой вопрос в посте Стефана Т. Лававея Особенности C ++ 11/14 STL, исправления и критические изменения в VS 2013:

Механизм VS Update в первую очередь предназначен для доставки исправлений с высоким приоритетом, а не для доставки новых функций, особенно массовых переписываний с критическими изменениями (которые связаны с такими же масштабными изменениями компилятора).

Основные версии, такие как Visual C ++ 2013, дают нам свободу изменять и ломать множество вещей. Мы просто не можем отправить этот материал в обновлении.

В5: Как насчет исправлений? Можем ли мы получить их в обновлении?

A5: Это интересный вопрос, потому что ответ зависит от моего выбора (тогда как в предыдущем вопросе мне не разрешили отправить такое переписывание в обновлении, даже если бы я захотел).

Каждая команда выбирает, какие исправления они вносят в «судовую комнату» для рассмотрения, чтобы включить в Обновление. Есть вещи, которые не позволят нам покинуть судовой склад (например, бинарные изменения запрещены вне основных версий), но в противном случае нам дают свободу действий. Я лично отдаю приоритет пропускной способности над задержкой — то есть я предпочитаю отправлять большее общее количество исправлений в каждой основной версии вместо того, чтобы отправлять меньшее общее количество исправлений (за тот же период времени) чаще в нескольких обновлениях.

7