gpt4 book ai didi

c - -Ofast 以外的任何内容都会导致 "undefined reference"错误

转载 作者:太空宇宙 更新时间:2023-11-04 01:05:08 26 4
gpt4 key购买 nike

我有一个 C 程序,其中包含 math.h 并使用该 header 中的 sqrt 函数。非常奇怪,当我不传递 -Ofast 标志时,我的代码无法编译。

如果我使用以下代码编译我的代码:

gcc -std=c99 foo.c

单独使用,或将 -O1-O2-Os(这些都是大写的 O)添加到该命令中,我收到以下错误:

/tmp/ccAcT2Bz.o: In function `sum_of_divisors':
foo.c:(.text+0xb): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status

-O3 给出了一个类似但更详细的错误(请注意,我没有在 main 中调用 sqrt):

/tmp/ccBKvvFS.o: In function `sum_of_divisors':
foo.c:(.text+0x5c): undefined reference to `sqrt'
/tmp/ccBKvvFS.o: In function `main':
foo.c:(.text.startup+0xe5): undefined reference to `sqrt'
foo.c:(.text.startup+0xf3): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status

但是,-Ofast 编译没有错误,程序运行完美。所以,

  • 为什么会这样?为什么必须启用特定的优化级别才能编译?是 GCC 错误吗?
  • 如果我选择不使用 -Ofast,我该如何修复它?

最佳答案

我会尝试根据我提供的评论将其表述为答案。

本质上,-ffast-math 允许不符合 IEEE-754 标准的数学“优化”。一些示例包括允许浮点运算遵守结合律,例如,它们表现得像“实数”:(a + b) + c == a + (b + c) - 和这不是 float 的正确假设。您可以查看 gcc 的手册页以了解 -ffast-math 启用的选项。

该选项还允许使用与 IEEE-754 标准不同的其他代码生成选项。应该引发异常、发出 NaN 信号等的操作可能不会被接受。评论中的例子是sqrt;如果我们将负值传递给 sqrt,结果可能不符合 IEEE-754 标准。试图找到这些不一致的根源远远超过现代处理器的任何好处。现代 CPU 拥有海量浮点资源,正确性远比任何错位的效率感重要。

有很多真实的例子说明在处理 float 时遵守实数的关联属性会导致不正确的结果。一个例子是 Kahan summation .它依赖于浮点运算的非关联属性。还有其他示例,其中数值算法的仔 segmentation 析依赖于 IEEE-754 属性。另一个例子是 Heron's formula对于三角形的面积。

数值分析是一个广阔的领域,IEEE-754 标准代表了一项非常仔细和深入研究的工作,旨在标准化浮点运算的特殊行为,以及它们与“实”数的朴素理想的偏差。它代表了在数值密集型计算方面数十年的研究和经验(更不用说挫折)的巨大努力。

有些人经常在这个网站上回答 float 问题,他们对该主题的了解比我广泛得多。我只是希望让你相信 -ffast-math 在很多情况下都是不明智的(通常具有更好数值条件的算法是更好的第一步),并引入极其困难的错误源寻找,其结果通常无法在其他平台上重现。像躲避瘟疫一样躲避它。

关于c - -Ofast 以外的任何内容都会导致 "undefined reference"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25439794/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com