[英]Anything other than -Ofast causes “undefined reference” error
I have a C program which includes math.h
and makes use of the sqrt
function from that header. 我有一个包含
math.h
的C程序,并使用了该标头中的sqrt
函数。 Very strangely, when I do not pass the -Ofast
flag, my code does not compile. 非常奇怪的是,当我不传递
-Ofast
标志时,我的代码无法编译。
If I use the following to compile my code: 如果我使用以下代码来编译我的代码:
gcc -std=c99 foo.c
Either by itself, or add any of -O1
, -O2
or -Os
(those are uppercase O's) to that command, I get the following error: 通过其自身或任何添加
-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
gives a similar, but more elaborate error (note that I don't call sqrt
within main
): -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
However, -Ofast
compiles without error and the program runs perfectly. 但是,
-Ofast
编译不会出错,并且程序可以完美运行。 So, 所以,
-Ofast
? -Ofast
,该如何解决? I'll try to phrase this as an answer based on the comments I've provided. 我将根据我提供的评论尝试将此短语作为答案。
Essentially -ffast-math
allows for mathematical 'optimizations' that do not conform to the IEEE-754 standard. 本质上,
-ffast-math
允许不符合IEEE-754标准的数学“优化”。 Some examples includes allowing floating-point operations to obey the laws of associativity, eg, they behave like 'real' numbers: (a + b) + c == a + (b + c)
- and this is not a correct assumption with floating-point numbers. 一些示例包括允许浮点运算遵循关联律,例如,它们的行为类似于“实数”:
(a + b) + c == a + (b + c)
-但这不是正确的假设浮点数字。 You can look at the man page for gcc
to see the options that -ffast-math
enables. 您可以在
gcc
的手册页中查看-ffast-math
启用的选项。
The option also allows for other code generation options that depart from the IEEE-754 standard. 该选项还允许使用其他与IEEE-754标准不同的代码生成选项。 Operations that should raise exceptions, signalling NaNs, etc., may not be honoured.
应该引发异常,发信号通知NaN等的操作可能无法兑现。 The example in the comments was
sqrt
; 评论中的示例是
sqrt
; if we pass a negative value to sqrt
, the results may not conform to the IEEE-754 standard. 如果我们将负值传递给
sqrt
,则结果可能不符合IEEE-754标准。 Trying to find the source of these inconsistencies far outweighs any benefit on modern processors. 试图找到这些不一致的根源远远超过了现代处理器的任何好处。 Modern CPUs have massive floating point resources, and correctness is far more important than any misplaced sense of efficiency.
现代CPU具有大量的浮点资源,正确性比任何错位的效率意义都重要。
There are very real examples of where honouring the associative property of real numbers when dealing with floating-point numbers leads to incorrect results. 有非常真实的示例,其中在处理浮点数时尊重实数的关联属性会导致错误的结果。 One example is Kahan summation .
卡汉求和就是一个例子。 It relies on the non-associative property of floating-point arithmetic.
它依赖于浮点算术的非关联属性。 There are other examples where careful analysis of numeric algorithms rely on IEEE-754 properties.
还有其他一些例子,其中数字算法的仔细分析依赖于IEEE-754属性。 Another example is Heron's formula for the area of a triangle.
另一个例子是苍鹭的三角形面积公式 。
Numerical analysis is a broad field, and the IEEE-754 standards represent a very careful and well-researched effort to standardize the idiosyncratic behaviour of floating-point operations, and their deviation from the naive ideal of 'real' numbers. 数值分析是一个广阔的领域,IEEE-754标准代表了非常仔细和深入研究的工作,旨在标准化浮点运算的行为以及它们与“实数”的天真理想的偏离。 It represents a massive effort over decades of research and experience (not to mention frustration) in numerically intensive computation.
它代表了数十年的数字密集型计算研究和经验(更不用说沮丧)了。
There are people who frequently answer floating-point questions on this site with a much broader knowledge of the topic than I have. 有些人经常在该站点上回答浮点问题,并且对该主题的了解比我广泛得多。 I just hope to convince you that
-ffast-math
is simply ill-advised in many cases (often an algorithm with better numerical conditioning is a better first step), and introduce sources of error that are extremely difficult to find, with results that are often impossible to reproduce on other platforms. 我只是希望说服您
-ffast-math
在许多情况下都是错误的建议(通常,具有更好数值条件的算法是更好的第一步),并介绍极难发现的错误源,其结果是通常无法在其他平台上复制。 Avoid it like the plague. 避免像瘟疫一样。
The math library must be linked in when building the executable 构建可执行文件时必须链接数学库
so you need to compile with -lm
option. 因此,您需要使用
-lm
选项进行编译。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.