Совместимость стандартной библиотеки ABI - PullRequest
1 голос
/ 24 марта 2020

Предположим, у нас есть общая библиотека, которая принимает или возвращает некоторый класс std:

//lib.h
#include <vector>

std::vector<int> returnSomeInts();

//lib.cpp
#include "lib.cpp"

std::vector<int> returnSomeInts() {
   return {1, 3, 5};
}

Итак, очевидно, что при компиляции общей библиотеки lib.so этот код должен был быть скомпилирован с определенным версия стандартной библиотеки, например, с -std = c ++ 11.

Теперь представьте, что у нас есть приложение, которое будет использовать нашу разделяемую библиотеку, но оно будет скомпилировано, например, с более новой библиотекой std. -std = c ++ 2a

//app.cpp
#include <lib.h>

int main()
   auto v = returnSomeInts();

   //Process v
}

Поскольку стандартная библиотека определяет встроенные классы, при изменении макета членов класса совместимость ABI нарушается, поэтому приведенный выше код не будет работать должным образом.

Мои вопросы: есть ли гарантия стабильности ABI с общими реализациями библиотеки std при компиляции с одним и тем же заголовком с использованием различных стандартов c ++? А при компиляции с разными версиями заголовков (например, libstdc ++ - 8 и libstdc ++ - 9)?

PD: приведенный выше код является лишь примером, я не имею в виду конкретно std::vector

Ответы [ 2 ]

3 голосов
/ 24 марта 2020

ABI на практике не связаны со стандартом, например, рассмотрим следующий код , скомпилированный с g cc 4.9.4 и g cc 5.1 с использованием тех же флагов:

-std = c ++ 11 -O2

#include <string>
int main(){
    return sizeof (std::string);
}

g cc 4.9.4 возвращает 8 от основной, g cc 5.1 возвращает 32.

Что касается гарантий: это сложно:

Стандарт не гарантирует ничего.

Практически MSV C используется для нарушения совместимости ABI, они остановлены (v140, v141, v142 используют то же самое ABI), clang / g cc имеют стабильный ABI в течение длительного времени.

Для тех, кто хочет узнать больше: Для широкого обсуждения стандарта ABI / C ++, который не имеет прямого отношения к этому вопросу, просмотрите этот пост blog .

2 голосов
/ 24 марта 2020

Ваш пример с std::vector не является проблемой. Как указывают другие ответы, компиляторы поддерживают совместимость, а std::vector довольно стар.

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

Например, у меня есть какой-то продукт, использующий C ++ 17 функций языка. Мой продукт поддерживает MacOS 10.13. Я могу построить свой проект, используя C ++ 17 (возможности языка), но я не могу использовать, например, std :: необязательный , так как некоторые методы выдают std :: bad_optional_access , который часть динамическая c библиотека, и это не поддерживается / не присутствует в MacOS 10.13. Clang предупреждает меня об этом (сообщает об ошибке).

То же самое относится и к другой системе (clang прекрасно это контролирует). Поэтому, когда вы используете некоторые библиотечные функции, вам необходимо убедиться, что библиотеки в развернутой системе поддерживают это (в Linux менеджеры пакетов прекрасно справляются с этим, если у системы нет доступа к требуемой версии пакета, установка не удастся). В Windows 10 AFAIK Windows при обновлении сохраняется самая последняя версия msv c, распространяемые более старые версии Windows требуют ручного обновления.

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

...