Что именно делает параметр GCC -Wpsabi? Каковы последствия его подавления?

Фон

В прошлом году я использовал json-библиотеку nlohmann [1] и выполнял кросс-компиляцию на x86_64 с использованием GCC 5.x arm-linux-gnueabi-* без предупреждений. Когда я обновлял GCC до более новой версии, GCC генерировал страницы загадочных диагностических заметок. Например, вот одна из заметок

In file included from /usr/arm-linux-gnueabi/include/c++/7/vector:69:0, from include/json.hpp:58, from src/write_hsi.cpp:23: /usr/arm-linux-gnueabi/include/c++/7/bits/vector.tcc: In member function ‘void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& …) [with _Args = {nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long long int, long long unsigned int, double, std::allocator, nlohmann::adl_serializer>}; _Tp = nlohmann::basic_json<>; _Alloc = std::allocator<nlohmann::basic_json<> >]’: /usr/arm-linux-gnueabi/include/c++/7/bits/vector.tcc:394:7: note: parameter passing for argument of type ‘std::vector<nlohmann::basic_json<>, std::allocator<nlohmann::basic_json<> > >::iterator {aka __gnu_cxx::__normal_iterator<nlohmann::basic_json<>*, std::vector<nlohmann::basic_json<>, std::allocator<nlohmann::basic_json<> > > >}’ changed in GCC 7.1 vector<_Tp, _Alloc>:: ^~~~~~~~~~~~~~~~~~~ /usr/arm-linux-gnueabi/include/c++/7/bits/vector.tcc: In member function ‘nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer> nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::parser::parse_internal(bool) [with ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]’: /usr/arm-linux-gnueabi/include/c++/7/bits/vector.tcc:105:21: note: parameter passing for argument of type ‘__gnu_cxx::__normal_iterator<nlohmann::basic_json<>*, std::vector<nlohmann::basic_json<>, std::allocator<nlohmann::basic_json<> > > >’ changed in GCC 7.1 _M_realloc_insert(end(), std::forward<_Args>(__args)…); ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Решение было легко найти, а именно добавлением -Wno-psabi к параметрам компилятора. Фактически, это было исправление, реализованное в библиотеке. [2]

Я понимаю основы двоичных интерфейсов приложений (ABI) и ABI для конкретных процессоров (psABI). Для справки, этот ответ [11] дает краткий обзор ABI:

ABI (Application Binary Interface) — это стандарт, который определяет соответствие между низкоуровневыми концепциями языков высокого уровня и возможностями машинного кода конкретной аппаратной платформы / платформы ОС. . Сюда входят такие вещи, как:

  • как C / C ++ / Fortran / … типы данных размещаются в памяти (размеры данных / выравнивание)
  • как работают вложенные вызовы функций (где и как хранится информация о том, как вернуться к вызывающему функцию, где в регистрах ЦП и / или в памяти передаются аргументы функции)
  • как работает запуск / инициализация программы (какой формат данных имеет «исполняемый файл», как код / ​​данные загружаются оттуда, как работают библиотеки DLL …)

Ответы на них следующие:

  • зависящий от языка (следовательно, у вас есть C ABI, C ++ ABI, Fortran ABI, Pascal ABI … даже спецификация байт-кода Java, хотя нацелена на «виртуальный» процессор вместо реального оборудования, является ABI),
  • зависит от операционной системы (MS Windows и Linux на одном оборудовании используют другой ABI),
  • зависит от оборудования / процессора (ABI для ARM и x86 различаются).
  • эволюционирует в течение (долгого) времени (существующие ABI часто обновлялись / редактировались, чтобы можно было использовать новые функции ЦП, например, указание, как регистры x86 SSE должны использоваться apps, конечно, было возможно только тогда, когда процессоры имели эти регистры, поэтому существующие ABI нуждались в уточнении).

Таким образом, ABI — это всеобъемлющий компонент, а одним из его компонентов (детали, относящиеся к «аппаратному обеспечению / ЦП») является psABI.

Моя проблема

У меня проблема

  1. Мне не нравится отключение предупреждений без понимания последствий.
  2. Совет «используйте -Wno-psabi, чтобы убрать заметки» кажется довольно распространенным советом для этих типов диагностических заметок, которые «внезапно появляются» после обновления компилятора. [2] [3] [4] Даже один из разработчиков GCC предлагает сделать это. [5]
  3. Ни -Wpsabi, ни -Wno-psabi не задокументированы [6] в руководстве GCC. [7]

В результате я не совсем уверен, что именно -Wno-psabi повлияет и не повлияет. Связанный вариант -Wabi задокументирован: [8]

-Wabi (C, Objective-C, C++ and Objective-C++ only)

Предупреждать, когда G ++ генерирует код, который, вероятно, несовместим с независимым от поставщика C ++ ABI …

Он также предупреждает об изменениях, связанных с psABI. К известным изменениям psABI на данный момент относятся:

  • Для SysV / x86-64 объединения с длинными двойными членами передаются в память, как указано в psABI. Например:

union U { long double ld; int i; };

union U всегда передается в памяти.

Мое понимание всего этого

  1. -Wabi будет генерировать предупреждения при изменении psABI.
  2. GCC 7 fixed an ABI bug[9] introduced in GCC 5 that affects ARM targets.
    • In the release notes it is stated «this is an ABI change.»[10]
    • По какой-то причине в примечаниях к выпуску указано, что соответствующие диагностические примечания создаются при использовании недокументированного -Wpsabi, а не документированного -Wabi.
    • Это изменение ABI не упоминается в руководстве.
  3. Если сложить вместе «это изменение ABI» и «использовать -Wpsabi», мне кажется, что это конкретно изменение psABI, а не другой вид изменения ABI. (На самом деле это изменение в реализации psABI в GCC, а не в самом psABI)

Я знаю, что документация не всегда актуальна, особенно для того, что является известным недокументированным вариантом. Но меня беспокоит то, что «use -Wno-psabi» кажется стандартным ответом на несколько различных типов этих загадочных диагностических заметок. Но в моем базовом понимании ABI, разве ABI не меняет большого дела? Разве меня не должно беспокоить изменение ABI, а не просто убрать сообщение? Между недокументированным материалом и некоторыми более тонкими деталями ABI vs psABI, я не совсем уверен …

Например, если я добавлю -Wno-psabi в свой make-файл, чтобы убрать эти заметки, что, если в будущем произойдет еще одно изменение ABI, которое повлияет на мой проект? Эффективно ли я заглушил будущие предупреждения или заметки, которые могут быть важны?

Кроме того, даже несмотря на то, что нам говорят «если вы перекомпилируете весь код, не о чем беспокоиться», [5] что именно такое «весь код»? Это мой исходный код? glibc? Любую другую общесистемную общую библиотеку, которую я мог бы использовать?

использованная литература

  1. https://github.com/nlohmann/json
  2. https://github.com/nlohmann/json/issues/658
  3. https://stackoverflow.com/a/48149400
  4. https://stackoverflow.com/a/13915796/10270632
  5. https://gcc.gnu.org/ml/gcc/2017-05/msg00073.html
  6. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81831
  7. https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc
  8. https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/C_002b_002b-Dialect-Options.html
  9. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77728
  10. https://gcc.gnu.org/gcc-7/changes.html
  11. https://stackoverflow.com/a/8063350

Освежающий хороший вопрос; проголосовать за.   —  person rmc    schedule 25.08.2018

@ jesper-juhl Спасибо. Я просмотрел SO, списки рассылки и т. Д. В поисках ответа. Я даже потратил немного времени на исходный код GCC, пытаясь понять это (и, возможно, смогу внести исправление, чтобы исправить отсутствующая документация), но я не был достаточно знаком с внутренним устройством GCC, чтобы понять это. Такое чувство, что забить гвоздь кувалдой, а потом забыть, что нормальные молотки существуют …   —  person rmc    schedule 25.08.2018

Мне просто грустно, что у меня нет для тебя хорошего ответа. Но, надеюсь, кто-нибудь зайдет, кто это сделает.   —  person rmc    schedule 25.08.2018

@ jesper-juhl Это делает нас двоих Я думаю, что когда-нибудь у меня возникнет вопрос, на который еще не было ответа SO, и я был бы вынужден создать учетную запись, чтобы спросить об этом.   —  person rmc    schedule 25.08.2018

Я не думаю, что это повлияет на вас. Если стандартная библиотека скомпилирована с той же версией GCC (я имею в виду версию, использующую тот же abi), которую вы используете (что вполне вероятно), все должно быть в порядке.   —  person rmc    schedule 25.08.2018

@geza Я не думаю, что стандартная библиотека принадлежит той же версии GCC. Эти сообщения появились, когда я обновил кросс-компилятор на главном компьютере x86_64. На целевой машине ARM установлен GCC 5.x. Я предполагаю, что это оставит мне выбор между переустановкой кросс-компилятора GCC 5.x, компиляцией на целевой машине, статической связью всего или поиском способа обновления пакетов на целевой машине, не подключенной к сети. . Кроме того, даже если это не проблема, я все равно хотел бы выяснить, на что влияет -Wpsabi (первая часть вопроса).   —  person rmc    schedule 25.08.2018

Poreferrer Дополнение ABI — поучительна глава «Введение». Я предполагаю, что изменения ABI или изменения PS ABI обрабатываются одинаково, но имеют два разных флага компилятора для подавления. Документы для -Wabi должны применяться также для _2 _ / _ 3_, где последнее относится к изменениям, связанным с соответствием PS ABI, а не ABI.   —  person rmc    schedule 26.08.2018

@rmc: А. Как-то я предположил, что вы нацеливаетесь на андроид. Обратите внимание: вполне вероятно, что приведенные вами предупреждения не причинят никакого вреда. Это шаблонный код, который включается в elf. Таким образом, между вашим кодом и скомпилированным libstdc ++ не будет несоответствия ABI. Но, конечно, вам нужно будет проверить все предупреждения, потому что, возможно, там есть что-то, что может быть потенциально плохим (вам, конечно, нужно перекомпилировать json-библиотеку nlohmann с новым компилятором).   —  person rmc    schedule 26.08.2018

Ссылаясь на System V ABI: Сегодня это стандартный ABI, используемый основными операционными системами Unix. .. ABI организован как переносимый базовый документ и приложения для конкретных платформ, которые заполняют пустые пробелы … Были опубликованы неофициальные дополнения к процессорам новой архитектуры, поскольку формат был адаптирован для новых платформ. .. Из-за множества неофициальных спецификаций дополнений и хаотичной истории операционных систем Unix … ABI хорошо понимают обычные инструменты разработки операционных систем, такие как Binutils и GCC.   —  person rmc    schedule 26.08.2018

Вы используете nlohmann только через заголовок, а не как архив библиотеки или совместно используемый объект?   —  person rmc    schedule 27.08.2018

Возможно, это связано с исправлением ошибок GCC. Вот новый экземпляр: gcc.gnu.org/gcc-9/changes.html < / а>.   —  person rmc    schedule 16.03.2020

@Peter, да, мы использовали nlohmann только как заголовок   —  person rmc    schedule 08.03.2021

@FrankHB Я думаю, это на самом деле иллюстрирует именно ту ситуацию, о которой я беспокоился, если бы отключил -Wpsabi. Предупреждение об изменении ABI, которое я обнаружил, появилось после обновления GCC 5.x до более новой версии (я не могу вспомнить, была ли это более новая версия 5.x или 6.x). Связанные вами изменения GCC 9 связаны с ошибкой On Arm … в выпусках GCC 6, 7 и 8 … Это изменение ABI. Если опция -Wpsabi включена … компилятор выдаст диагностическое сообщение … Если бы я поместил -Wno-psabi в свой make-файл 2 года назад при использовании GCC 5.x, он бы подавил предупреждения на этом более позднем ABI изменение.   —  person rmc    schedule 08.03.2021

Источник: ledsshop.ru

Стиль жизни - Здоровье!