当尝试时优化 x86_64 上的返回值 https://stackoverflow.com/q/25381736/3919155,我注意到一个奇怪的事情。即,给定代码:
#include <cstdint>
#include <tuple>
#include <utility>
using namespace std;
constexpr uint64_t a = 1u;
constexpr uint64_t b = 2u;
pair<uint64_t, uint64_t> f() { return {a, b}; }
tuple<uint64_t, uint64_t> g() { return tuple<uint64_t, uint64_t>{a, b}; }
Clang 3.8 输出 https://gcc.godbolt.org/#compilers:!((compiler:clang380,options:'-std%3Dc%2B%2B11+-O2',sourcez:MQSwdgxgNgrgJgUwAQB4IGcAudyYHwBQoksiqmMADlAocdPMijJiFCJgJ6EEzrgBzJGACGAWwTpKIiMixwA3AQIQA9mCwIAHpQBOSGLgBsAFgD6mJCKQBeJAEYYStRsza9B4%2BcsAjW0gAmJ2VpEF1mLwsAGk8wTFMLPCQAMwAKAEokAG8kXQQKXTBskRifAF8FJDKCCmoECLiEzBjDRu8kgQzs3PyYQqRamgb47xbI/CySpHLK6oIsEVYIMxF0dARdTFT%2BAC8EVTTQ8NaR6NjT/HSCJBvbu7ubO139tJOmzIBqJGeD1LfvdIxABEQPSSgWSxWaw2Wx%2BaUG9X%2BZyRl2u93RN0e3xAe1%2BR2GTTGbUSgKQILBQAAA%3D%3D)),filterAsm:(commentOnly:!t,directives:!t,labels:!t),version:3该汇编代码为f
:
movl $1, %eax
movl $2, %edx
retq
这对于g
:
movl $2, %eax
movl $1, %edx
retq
看起来最优。然而,当使用 GCC 6.1 编译 https://gcc.godbolt.org/#compilers:!((compiler:g6,options:'-std%3Dc%2B%2B11+-O2',sourcez:MQSwdgxgNgrgJgUwAQB4IGcAudyYHwBQoksiqmMADlAocdPMijJiFCJgJ6EEzrgBzJGACGAWwTpKIiMixwA3AQIQA9mCwIAHpQBOSGLgBsAFgD6mJCKQBeJAEYYStRsza9B4%2BcsAjW0gAmJ2VpEF1mLwsAGk8wTFMLPCQAMwAKAEokAG8kXQQKXTBskRifAF8FJDKCCmoECLiEzBjDRu8kgQzs3PyYQqRamgb47xbI/CySpHLK6oIsEVYIMxF0dARdTFT%2BAC8EVTTQ8NaR6NjT/HSCJBvbu7ubO139tJOmzIBqJGeD1LfvdIxABEQPSSgWSxWaw2Wx%2BaUG9X%2BZyRl2u93RN0e3xAe1%2BR2GTTGbUSgKQILBQAAA%3D%3D)),filterAsm:(commentOnly:!t,directives:!t,labels:!t),version:3,而生成的程序集为f
与 Clang 输出相同,生成的程序集g
is:
movq %rdi, %rax
movq $2, (%rdi)
movq $1, 8(%rdi)
ret
看起来返回值的类型被 GCC 分类为 MEMORY,但被 Clang 分类为 INTEGER。我可以确认将 Clang 代码与 GCC 代码链接,此类代码可能会导致分段错误(Clang 调用 GCC 编译的g()
写入任何地方%rdi
碰巧指向)并且返回无效值(GCC 调用 Clang 编译g()
)。哪个编译器有问题?
Related:
- 构建共享库时,G++ 和 clang++ 与标准库不兼容? https://stackoverflow.com/q/35586332/3919155
- [cxx-abi-dev] 不平凡的移动构造函数 http://sourcerytools.com/pipermail/cxx-abi-dev/2016-February/002884.html
See also
- System V 应用程序二进制接口。 AMD64 架构处理器补充。草案版本0.99.5 http://www.x86-64.org/documentation/abi.pdf