背景
In the last year I was using the nlohmann json library[1] and was cross-compiling on x86_64 using GCC 5.x arm-linux-gnueabi-*
with no warnings. When I updated GCC to a newer version, GCC would generate pages of cryptic diagnostic notes. For example, here is one of the notes
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)...);
~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It was easy to find a solution, namely by adding -Wno-psabi
to the compiler options. In fact, that was the fix implemented in the library.[2]
I understand the basics of Application Binary Interfaces (ABIs) and processor-specific ABIs (psABIs). For reference, this answer[11] gives a quick overview of ABIs:
An ABI (应用程序二进制接口)是定义高级语言中的低级概念与特定硬件/操作系统平台的机器代码的能力之间的映射的标准。这包括:
- 如何使用 C/C++/Fortran/...数据类型布置在内存中(数据大小/对齐方式)
- 如何嵌套函数调用工作(有关如何返回函数调用者的信息存储在何处以及如何存储,在 CPU 寄存器和/或内存中传递函数参数的位置)
- how 程序启动/初始化有效(“可执行文件”具有什么数据格式、如何从那里加载代码/数据、DLL 如何工作...)
这些问题的答案是:
-
特定于语言的(因此,您有 C ABI、C++ ABI、Fortran ABI、Pascal ABI,...甚至 Java 字节码规范,尽管针对的是“虚拟”处理器而不是真正的硬件,但也是 ABI),
-
操作系统特定(同一硬件上的 MS Windows 和 Linux 使用不同的 ABI),
-
特定于硬件/CPU(ARM 和 x86 ABI 不同)。
-
随着(长时间)时间的发展(现有的 ABI 经常被更新/修订,以便可以利用新的 CPU 功能,例如,指定应用程序如何使用 x86 SSE 寄存器当然只有在 CPUhad这些法规,因此需要澄清现有的 ABI)。
因此,ABI 是首要组件,其组件之一(“特定于硬件/CPU”的详细信息)是 psABI。
My Issue
我遇到的问题是
- 我不喜欢在不了解其含义的情况下普遍禁用警告。
- The advice "use
-Wno-psabi
to make the notes go away" seems to be pretty common advice for these types of diagnostic notes that "suddenly appear" after a compiler upgrade.[2][3][4] Even the one of the GCC developers suggest doing this.[5]
- Neither
-Wpsabi
nor -Wno-psabi
are documented[6] in the GCC manual.[7]
As a result I am not really sure what exactly -Wno-psabi
will and will not affect. A related option -Wabi
is documented:[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
总是在内存中传递。
我对这一切的理解是
-
-Wabi
当 psABI 发生变化时将生成警告。
- 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 更改。
- 将“这是 ABI 更改”和“使用
-Wpsabi
“,在我看来这是具体来说psABI 变化,而不是另一种 ABI 变化。 (实际上,这是 GCC 对 psABI 实现的更改,而不是 psABI 本身)
我知道文档并不总是最新的,特别是对于已知的未记录选项。但我担心的是“使用-Wno-psabi
“似乎是对几种不同类型的神秘诊断记录的标准反应。但是,根据我对 ABI 的基本理解,ABI 变化难道不是一件大事吗?难道我不应该担心 ABI 变化,而不仅仅是担心 ABI 变化吗?”让消息消失?在未记录的内容和 ABI 与 psABI 的一些更详细的细节之间,我不太确定......
例如,如果我添加-Wno-psabi
到我的 makefile 以使这些注释消失,如果将来有另一个 ABI 更改怎么办?does影响我的项目?我是否有效地消除了未来可能重要的警告或注释?
Also, even though we are told "if you recompile all the code, there is nothing to worry about,"[5] what exactly is "all the code"? Is that my source code? glibc? Any other system-wide shared library I might be using?
参考
- https://github.com/nlohmann/json https://github.com/nlohmann/json
- https://github.com/nlohmann/json/issues/658 https://github.com/nlohmann/json/issues/658
- https://stackoverflow.com/a/48149400 https://stackoverflow.com/a/48149400
- https://stackoverflow.com/a/13915796/10270632 https://stackoverflow.com/a/13915796/10270632
- https://gcc.gnu.org/ml/gcc/2017-05/msg00073.html https://gcc.gnu.org/ml/gcc/2017-05/msg00073.html
- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81831 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81831
- https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc
- https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/C_002b_002b-Dialect-Options.html https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/C_002b_002b-Dialect-Options.html
- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77728 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77728
- https://gcc.gnu.org/gcc-7/changes.html https://gcc.gnu.org/gcc-7/changes.html
- https://stackoverflow.com/a/8063350 https://stackoverflow.com/a/8063350