背景
去年,我使用了nlohmann json库[1],并且使用GCC 5.x在x86_64上进行了交叉编译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(应用程序二进制接口)是一种标准,它定义了高级语言中的低级概念与特定硬件/ OS平台的机器代码的功能之间的映射。包括以下内容:
- 如何在内存中布局C / C ++ / Fortran / ...数据类型(数据大小/对齐方式)
- 嵌套函数调用的工作方式(有关如何返回函数调用者的信息的存储位置和方式,在CPU寄存器和/或内存中传递函数参数的位置)
- 如何程序启动/初始化作品(“可执行”已经,如何代码/数据是从那里,怎么DLL的加载工作什么样的数据格式...)
这些问题的答案是:
- 特定于语言的语言(因此,您拥有C ABI,C ++ ABI,Fortran ABI,Pascal ABI……甚至Java字节码规范,尽管它针对的是“虚拟”处理器而不是真正的硬件,但它都是ABI),
- 特定于操作系统的(同一硬件上的MS Windows和Linux使用不同的ABI),
- 特定于硬件/ CPU(ARM和x86 ABI不同)。
- 随着时间的推移而发展(现有ABI经常被更新/修订,以便可以利用新的CPU功能,例如,指定应用程序如何使用x86 SSE寄存器当然只有一次CPU具有这些规则,因此需要澄清现有的ABI。
因此,ABI是总体组件,而其组件之一(“特定于硬件/ CPU”的细节)是psABI。
我的问题
我遇到的问题是
- 我不喜欢在不理解其含义的情况下普遍禁用警告。
- 对于
-Wno-psabi
编译器升级后“突然出现”的这些类型的诊断注释,“用于使注释消失的建议”似乎是非常普遍的建议。[2] [3] [4]甚至一位GCC开发人员都建议这样做。[5] - GCC手册中也
-Wpsabi
没有-Wno-psabi
记录[6]。[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
总是在内存中传递。
我对这一切的理解是
-Wabi
psABI更改时,将生成警告。- GCC 7修复了GCC 5中引入的会影响ARM目标的ABI错误[9]。
- 在发行说明中指出“这是ABI更改”。[10]
- 出于某种原因,发行说明指出,相关的诊断说明是在使用未说明
-Wpsabi
而不是未说明的文档时生成的-Wabi
。 - 手册中未提及此ABI更改。
- 将“这是ABI更改”和“使用
-Wpsabi
”放在一起,在我看来这是专门的一个psABI改变,而不是一种别样ABI的变化。(实际上,这是GCC对psABI实施的更改,而不是psABI本身)
我知道文档并不总是最新的,尤其是对于某些已知的无文档记录的选项。但我担心的是-Wno-psabi
”似乎是这些神秘诊断笔记中几种不同类型的标准响应。但是,以我对ABI的基本理解,ABI的变化不是很大吗?我是否应该关注ABI的变化,而不仅仅是让信息消失?在未记录的内容和ABI与psABI的一些更详细的细节之间,我不确定...
例如,如果我添加-Wno-psabi
到我的makefile文件,使这些笔记消失,如果有什么,在未来的另一ABI的变化呢影响了我的项目怎么办?我是否有效地消除了将来可能很重要的警告或注意事项?
同样,即使我们被告知“如果重新编译所有代码,也没有什么可担心的”,[5] “所有代码”到底是什么?那是我的源代码吗?glibc?我可能正在使用其他系统范围的共享库吗?
参考文献
- https://github.com/nlohmann/json
- https://github.com/nlohmann/json/issues/658
- https://stackoverflow.com/a/48149400
- https://stackoverflow.com/a/13915796/10270632
- https://gcc.gnu.org/ml/gcc/2017-05/msg00073.html
- 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/C_002b_002b-Dialect-Options.html
- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77728
- https://gcc.gnu.org/gcc-7/changes.html
- https://stackoverflow.com/a/8063350