返回元组时 GCC/Clang x86_64 C++ ABI 不匹配? [英] GCC/Clang x86_64 C++ ABI mismatch when returning a tuple?

查看:24
本文介绍了返回元组时 GCC/Clang x86_64 C++ ABI 不匹配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在尝试优化 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆