返回元组时 GCC/Clang x86_64 C++ ABI 不匹配? [英] GCC/Clang x86_64 C++ ABI mismatch when returning a tuple?
问题描述
在尝试优化 x86_64 上的返回值时,我注意到了一件奇怪的事情.即,给定代码:
When trying to optimize return values on x86_64, I noticed a strange thing. Namely, given the code:
#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}; }
锵3.8输出 f
的汇编代码:
movl $1, %eax
movl $2, %edx
retq
这对于g
:
movl $2, %eax
movl $1, %edx
retq
看起来最佳.但是,当使用GCC编译6.1,虽然为 f
生成的程序集与 Clang 输出的相同,但为 g
生成的程序集是:
which look optimal. However, when compiled with GCC 6.1, while the generated assembly for f
is identical to what Clang output, the assembly generated for 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()
).哪个编译器有问题?
It looks like the type of the return value is classified as MEMORY by GCC but as INTEGER by Clang. I can confirm that linking Clang code with GCC code such code can result in segmentation faults (Clang calling GCC-compiled g()
which writes to wherever %rdi
happens to point) and an invalid value being returned (GCC calling Clang-compiled g()
). Which compiler is at fault?
推荐答案
正如 davmac 的回答所示,libstdc++ std::tuple
是简单的复制构造,但不是简单的移动构造.两个编译器在移动构造函数是否应该影响参数传递约定上存在分歧.
As davmac's answer shows, the libstdc++ std::tuple
is trivially copy constructible, but not trivially move constructible. The two compilers disagree on whether the move constructor should affect the argument passing conventions.
您链接的 C++ ABI 线程似乎解释了这种分歧:http://sourcerytools.com/pipermail/cxx-abi-dev/2016 年 2 月/002891.html
The C++ ABI thread you linked to seems to explain that disagreement: http://sourcerytools.com/pipermail/cxx-abi-dev/2016-February/002891.html
总而言之,Clang 完全实现了 ABI 规范所说的内容,但 G++ 实现了应该所说的内容,但没有更新为实际所说的内容.
In summary, Clang implements exactly what the ABI spec says, but G++ implements what it was supposed to say, but wasn't updated to actually say.
这篇关于返回元组时 GCC/Clang x86_64 C++ ABI 不匹配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!