[英]Anything other than -Ofast causes “undefined reference” error
我有一個包含math.h
的C程序,並使用了該標頭中的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
編譯不會出錯,並且程序可以完美運行。 所以,
-Ofast
,該如何解決? 我將根據我提供的評論嘗試將此短語作為答案。
本質上, -ffast-math
允許不符合IEEE-754標准的數學“優化”。 一些示例包括允許浮點運算遵循關聯律,例如,它們的行為類似於“實數”: (a + b) + c == a + (b + c)
-但這不是正確的假設浮點數字。 您可以在gcc
的手冊頁中查看-ffast-math
啟用的選項。
該選項還允許使用其他與IEEE-754標准不同的代碼生成選項。 應該引發異常,發信號通知NaN等的操作可能無法兌現。 評論中的示例是sqrt
; 如果我們將負值傳遞給sqrt
,則結果可能不符合IEEE-754標准。 試圖找到這些不一致的根源遠遠超過了現代處理器的任何好處。 現代CPU具有大量的浮點資源,正確性比任何錯位的效率意義都重要。
有非常真實的示例,其中在處理浮點數時尊重實數的關聯屬性會導致錯誤的結果。 卡漢求和就是一個例子。 它依賴於浮點算術的非關聯屬性。 還有其他一些例子,其中數字算法的仔細分析依賴於IEEE-754屬性。 另一個例子是蒼鷺的三角形面積公式 。
數值分析是一個廣闊的領域,IEEE-754標准代表了非常仔細和深入研究的工作,旨在標准化浮點運算的行為以及它們與“實數”的天真理想的偏離。 它代表了數十年的數字密集型計算研究和經驗(更不用說沮喪)了。
有些人經常在該站點上回答浮點問題,並且對該主題的了解比我廣泛得多。 我只是希望說服您-ffast-math
在許多情況下都是錯誤的建議(通常,具有更好數值條件的算法是更好的第一步),並介紹極難發現的錯誤源,其結果是通常無法在其他平台上復制。 避免像瘟疫一樣。
構建可執行文件時必須鏈接數學庫
因此,您需要使用-lm
選項進行編譯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.