C 强制64位长双倍?

C 强制64位长双倍?,c,floating-point,clang,arm64,musl,C,Floating Point,Clang,Arm64,Musl,我在一个aarch64(arm64位)平台上静态构建一个项目。我希望避免任何软浮点库,例如。但是,即使在我使用-mfloat abi=hard时,这些文件仍会出现在库档案中。据我所知,这是因为ARM 64位平台将长双精度定义为128位 有没有办法改变这种行为?例如,我是否可以强制将long double定义为与double相同的大小?我知道这是C标准允许的,但我不确定是否有任何方法可以强制使用Clang(我为此专门使用Clang)来编译这样一个定义。我以前也曾做过类似的事情,用类型(特别是lon

我在一个
aarch64
(arm64位)平台上静态构建一个项目。我希望避免任何软浮点库,例如。但是,即使在我使用
-mfloat abi=hard
时,这些文件仍会出现在库档案中。据我所知,这是因为ARM 64位平台将长双精度定义为128位


有没有办法改变这种行为?例如,我是否可以强制将
long double
定义为与
double
相同的大小?我知道这是C标准允许的,但我不确定是否有任何方法可以强制使用Clang(我为此专门使用Clang)来编译这样一个定义。

我以前也曾做过类似的事情,用类型(特别是
long
s)来处理。最好的办法是手动替换类型,因为这是获得所需内容的最简单、最直接的方法。你可以试着用宏玩把戏或者修改编译器,但是根据我的经验,你只会产生比你解决的问题更多的问题,而且这通常是一个脆弱的解决方案,以后会崩溃

幸运的是,您正在使用的源代码看起来维护得很好,并且您正在寻找的更改非常简单。你可以很简单地解决这个问题。假设您运行的是类Unix系统,则可以从musl的基本目录运行以下命令:

$ grep -Rl 'long double' * | xargs -tn1 sed -i '' -e 's/long double/double/g'
此命令:

  • 在所有文件中递归查找字符串
    long double
    ,并返回包含该字符串的文件名
  • 它被传递到
    xargs
    ,xargs调用每个文件名的
    sed
    命令,并随文件一起打印
  • 当运行
    sed
    时,它会就地修改文件,并用
    double
    替换
    long double

  • 当我尝试这个命令时,它“刚刚起作用”。我会更仔细地阅读diff,以确保它符合所有要求,并且不会改变库的行为。

    我最终找到了一个解决方案,尽管我不一定推荐给所有人。它可能会在其他地方引发bug,但它已经足够满足我的需要了。它还包括从头开始构建叮当声(感谢@Art!)。此外,我正在从事的项目使用的是LLVM/Clang 3.7.1,因此我不主张使用其他版本


    据我所知,AArch64目标的长双精度定义出现在:

    通过修改内部2行,我删除了对我在问题中提到的软FP例程的任何引用:

    LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
    LongDoubleFormat = &llvm::APFloat::IEEEdouble;
    

    我的测试程序--仍然正确地验证,所以我假设我没有太严重地破坏任何东西。不过,这是一个非常重要的修改——我不建议大多数人使用它(它可能会导致其他地方破损)。

    试试
    -mlong-double-64
    。不确定是否适用于ARM…@AndrewHenle:我假设软浮点库例程的出现仅仅是因为
    long double
    被定义为128位(基于
    \uu extenddftff2
    描述以及我知道我的
    aarch64
    平台有64位FP寄存器的事实)。因此,虽然是的,
    vfprintf
    依赖于
    long double
    处理,但我想知道的是
    long double
    处理是否反过来依赖于软浮点库例程。这有意义吗?@AndrewHenle:换句话说,如果
    vfprintf
    依赖于
    long double
    处理,那么
    long double
    的大小是否会改变该处理?如果是这样的话,我可以利用这一事实强制长双精度的大小适应硬浮点寄存器,而不是使用软浮点吗?我知道这很可怕,但为了验证你的假设,为什么不执行查找替换(将“长双精度”替换为“双精度”)在我记忆中的整个库中?@tonysdg(这是一个永恒的过去),这需要重建编译器。也许叮当声是不同的,但对于gcc来说,这是唯一的选择。尽管我们确实大声发誓,体系结构定义了没有CPU(至今)拥有的类型和指令。事实上,我现在回想起来,我们的问题是双重的。在重建gcc之后,我们需要使用这些中止存根函数,以避免生成没有CPU实现的指令,并且我们没有在内核中进行仿真(就像其他人一样)。我有一个类似的例子:ppc32,gcc将长双精度运算编译成uu gcc_qsub/qmult/etc调用。GCC可以在没有quadmath的情况下编译工作,基本上可以将长的double减少到double。到目前为止,Clang不支持这一点。在源代码中更改它帮助了我!
    LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
    LongDoubleFormat = &llvm::APFloat::IEEEdouble;