我可以在我的機器上手動構建自己的 .sln,或者讓 Azure DevOps 在遠程機器上構建它。該軟體面向 .NET Core 3.1,并使用 C 17。我注意到從同一個分支構建相同的代碼會產生不同大小的 .exe:遠程的比本地的少 9 KB。
當我升級遠程機器的 Visual Studio 2019 版本以匹配我的(從 16.8.something 到 16.11.14)時,我終于得到了相同的結果。但是如何解釋這種差異呢?較小的檔案中是否缺少某些內容?它應該具有所有相同的方法、邏輯和功能。沒有錯誤,所以它的任何部分都不會編譯失敗。
我還必須使用 Maven 構建 Java 專案,并且聽說可以根據 Maven 版本“稍微不同”地構建它。起初這是有道理的,但事后我不知道這到底是什么意思。
有沒有人真正在使用軟體構建(特別是使用 Visual Studio 及其 C 編譯器)來解釋這個“略有不同的構建”的概念,或者有一個好主意?
兩個版本在功能上是否相同,或者沒有簡單的方法來判斷?
uj5u.com熱心網友回復:
C 標準沒有規定應該由編譯器生成的機器代碼。它只是指定了預期的可觀察行為。
因此,例如,如果您有一個for回圈,則標準規定了行為(初始化、檢查條件等)。但是您可以通過多種方式轉換為機器代碼,例如使用不同的暫存器,或者以不同的順序執行陳述句(只要可觀察的行為相同)。
這個原則被稱為as-if rule。
所以不同的編譯器(或編譯器版本)可以產生不同的機器代碼。原因可能是不同的優化,或者將 C 轉換為機器代碼的不同方式(因為 C 和機器代碼之間的映射不是 1-1)。
與優化相關的示例:如果代碼中有各種不相關的陳述句(例如,您修改了不同的不相關變數),如果記憶體訪問模式更有效,編譯器/優化器可能會重新排序它們。或者編譯器/優化器可能會消除沒有可觀察行為的陳述句(比如增加一個之后永遠不會讀取的變數)。另一個例子是函式是否被行內,這完全取決于編譯器/優化器,并影響二進制代碼。
因此,編譯的二進制檔案的大小(或內容)沒有保證。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/475872.html
