-Ofast 以外的任何内容都会导致“未定义的引用"错误 [英] Anything other than -Ofast causes "undefined reference" error

查看:96
本文介绍了-Ofast 以外的任何内容都会导致“未定义的引用"错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含 math.h 的 C 程序,并利用了该头文件中的 sqrt 函数.很奇怪,当我没有通过 -Ofast 标志时,我的代码不会编译.

I have a C program which includes math.h and makes use of the sqrt function from that header. Very strangely, when I do not pass the -Ofast flag, my code does not compile.

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

If I use the following to compile my code:

gcc -std=c99 foo.c

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

Either by itself, or add any of -O1, -O2 or -Os (those are uppercase O's) to that command, I get the following error:

/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):

-O3 gives a similar, but more elaborate error (note that I don't call sqrt within main):

/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 编译没有错误,程序运行完美.所以,

However, -Ofast compiles without error and the program runs perfectly. So,

  • 为什么会发生这种情况?为什么必须启用某个优化级别才能编译?是 GCC 错误吗?
  • 如果我选择不使用 -Ofast,我该如何解决?
  • Why does this happen? Why must a certain optimization level be enabled for it to compile? Is it a GCC bug?
  • How can I fix it, if I choose not to use -Ofast?

推荐答案

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

I'll try to phrase this as an answer based on the comments I've provided.

基本上 -ffast-math 允许不符合 IEEE-754 标准的数学优化".一些示例包括允许浮点运算遵守结合律,例如,它们的行为类似于实数":(a + b) + c == a + (b + c) - 和这对于浮点数来说不是一个正确的假设.您可以查看 gcc 的手册页以查看 -ffast-math 启用的选项.

Essentially -ffast-math allows for mathematical 'optimizations' that do not conform to the IEEE-754 standard. Some examples includes allowing floating-point operations to obey the laws of associativity, e.g., they behave like 'real' numbers: (a + b) + c == a + (b + c) - and this is not a correct assumption with floating-point numbers. You can look at the man page for gcc to see the options that -ffast-math enables.

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

The option also allows for other code generation options that depart from the IEEE-754 standard. Operations that should raise exceptions, signalling NaNs, etc., may not be honoured. The example in the comments was sqrt; if we pass a negative value to sqrt, the results may not conform to the IEEE-754 standard. 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.

在处理浮点数时尊重实数的关联属性会导致不正确的结果,有很多真实的例子.一个例子是Kahan summation.它依赖于浮点运算的非关联特性.还有其他一些示例,其中对数值算法的仔细分析依赖于 IEEE-754 属性.另一个例子是三角形面积的海伦公式.

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. Another example is Heron's formula for the area of a triangle.

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

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. It represents a massive effort over decades of research and experience (not to mention frustration) in numerically intensive computation.

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

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. Avoid it like the plague.

这篇关于-Ofast 以外的任何内容都会导致“未定义的引用"错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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