簡體   English   中英

C語言If語句

[英]C language If statement

我是C語言的新手,正在嘗試弄清楚以下代碼的含義。

在這里if (!msize)檢查msize是否為零或msize是否為NULL?

if (!msize)
    msize = 1 / msize; /* provoke a signal */

//Example 1: A division-by-zero misuse, in lib/mpi/mpi-pow.c of the Linux kernel, where the entire code will be optimized away. 
//Compilers, GCC 4.7 and Clang 3.1

這取決於msize的類型。

  • 如果msize是一個指針,它將測試它是否為NULL

  • 如果msize不是指針,則測試它是否為0

這種區別似乎很古怪,但這很重要。 盡管在大多數系統上NULL實際上為0 ,但C標准允許它為任何其他值。


我做了一些進一步的閱讀,因為我開始懷疑我上面的理解是否正確。

這是C標准的相關部分。

§6.5.3.3一元算術運算符

(5)邏輯求反運算符的結果! 如果其操作數的值比較不等於0,則為0;如果其操作數的值比較等於0,則為1。結果的類型為int 表達式!E等效於(0==E)

§6.3.2.3指針

(3)值為0的整數常量表達式,或強制類型為void *的表達式,稱為空指針常量 66 )如果將空指針常量轉換為指針類型,則保證生成的指針(稱為空指針)將不相等的值與指向任何對象或函數的指針進行比較。

(6)任何指針類型都可以轉換為整數類型。 除非先前指定,否則結果是實現定義的。 如果結果不能用整數類型表示,則行為未定義。 結果不必在任何整數類型的值范圍內。

腳注: 66NULL<stddef.h> (和其他頭文件)中定義為空指針常量。 見7.19。

如您所見,0在C語言中是一個魔幻數字。對於具有非零NULL ,我希望!msize的實際行為可能是實現定義的。 無論如何,這有點挑剔。

我在論文中找到了示例的來源: 未定義的行為:我的代碼發生了什么? 討論您的示例的文字指出:

如前所述,在指令集級別,x86引發了一個除以零的例外情況[17,3.2],而MIPS [22,A.6]和PowerPC [15,3.3.38]默默地忽略了它。 用C除以零是未定義的行為[19,6.5.5],因此編譯器可以簡單地假定除數始終為非零。

圖1顯示了Linux內核中的零除誤用。 從程序員的評論很明顯,目的是在msize為零的情況下發出錯誤信號。 使用GCC進行編譯時,此代碼在x86上的行為符合預期,但在PowerPC上卻不起作用,因為它不會生成異常。 使用Clang進行編譯時,結果更加令人驚訝。 Clang假定除數msize在任何系統上都必須為非零值,因為否則除法是不確定的。 結合此假設,零檢查!msize始終為false,因為msize不能同時為零和非零。 編譯器確定整個代碼塊不可訪問並將其刪除,這具有意想不到的效果,即消除了msize為零時程序員防范這種情況的初衷。

因此,在您的情況下,您真正​​需要的答案是:它測試msize是否為0。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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