簡體   English   中英

-Ofast以外的任何其他東西都會導致“未定義的引用”錯誤

[英]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編譯不會出錯,並且程序可以完美運行。 所以,

  • 為什么會這樣? 為什么必須啟用某個優化級別才能進行編譯? 是GCC錯誤嗎?
  • 如果選擇不使用-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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM