【问题标题】:the ABI of passing union with long double has changed in GCC 4.4GCC 4.4 中使用 long double 传递联合的 ABI 已更改
【发布时间】:2013-05-30 08:04:10
【问题描述】:

我有一个长双字段的联合。

我初始化一个字段并将其传递给一个函数。

my_union foo;
foo.long_double = 10.10;
bar = baz(foo);

编译这段代码时,我得到:

the ABI of passing union with long double has changed in GCC 4.4

似乎和这里提到的变化有关:http://gcc.gnu.org/gcc-4.4/changes.html

这是否意味着我不能通过具有 long double 作为字段的联合?为什么是这样?既然我想使用 long double 来存储大值,我该如何解决这个问题。

【问题讨论】:

    标签: c


    【解决方案1】:

    这意味着生成的代码与使用先前版本的 GCC 编译的代码二进制不兼容,因此如果您在使用当前版本和先前版本编译的二进制文件之间的库之间传递它,它将无法工作。 (有关网络传输和保存到文件的内存布局的信息,请参阅 cmets)

    从您提供的链接中可以看出:

    Code built with previous versions of GCC that uses any of these is not compatible with code built with GCC 4.4.0 or later.

    要么不要这样做,要么确保使用更改日志中提到的联合的所有代码都在相同的编译器版本(或技术上的 ABI)上编译。

    http://en.wikipedia.org/wiki/Application_binary_interface

    【讨论】:

    • 一个澄清:文档说将这些联合作为参数传递的 ABI 已经改变,而不是它们的内存布局(可能涉及的寄存器)。因此,通过网络移动它们或将它们保存在文件中应该是安全的。
    • 我将字段更改为双倍,现在可以使用。但是为什么禁止长双的设计决定呢?
    • 那么为什么决定可以通过双字段的联合,但不能通过长双字段?
    • 没关系。在使用不同版本编译的库中这样做是不行的。
    • 就像.. 他们只需要改变一些不向后兼容的东西。你还是可以做的,做这件事从来没有错,他们只是做了一个改变,你不能同时使用旧版本和新版本。只需重新编译任何旧代码(这可能甚至不会影响您),您将使用此联合与旧编译器一起使用,您就可以了。
    【解决方案2】:

    在编译时尝试使用选项 -msse2 或 -march=k8

    【讨论】:

    • 从 gcc 变更日志的描述来看,新版本可能是正确的方法,因此在寻找可能无法解决的变通方法之前,您应该尝试使其按现在的方式工作是必要的。但如果你需要它,这可能值得一看——我不知道。
    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-27
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    • 1970-01-01
    相关资源
    最近更新 更多