2013-07-15 269 views
0

我們遷移從RHEL 5.3 32位應用程序,以6.4(char)NULL,' 0'和0在C的memset中意味着相同的東西?

我們正在「一個指針轉換爲大小不同的整數」關於新系統的memset的警告。

難道(char)NULL,'\0'0都意味着在C的memset中同樣的事情?

以下代碼在新環境中發出警告。

#define NULLC (char)NULL 
#define MAX_LEN 11 
… 
memset(process_name, NULLC, MAX_LEN + 1); 
strncpy(process_name, "oreo", MAX_LEN); 
+0

發佈引起問題的代碼行。卡爾森提供了一個正確的答案,但它可能無法幫助你,因爲你沒有發佈相關的代碼。 – Gilles

+0

以下代碼在新環境中發出警告。 的#define NULLC(炭)NULL 的#define MAX_LEN 11 memset的(PROCESS_NAME,NULLC,MAX_LEN + 1); strncpy(process_name,「oreo」,MAX_LEN); – 2013-07-15 22:04:34

+1

將'NULLC'定義爲'(char)NULL'的任何理由? – Karlson

回答

8

做的不是都意味着同樣的事情,雖然他們可能會產生相同的結果。

(char)NULLNULL(實現定義的空指針常量)的值轉換爲charNULL的類型可以是intvoid*或其他某種整數類型。如果它是整數類型,則轉換已定義好併產生0。如果它是void*,那麼您將空指針的值轉換爲char,該值具有實現定義的結果(可能但不能保證爲0)。

NULL是指一個空指針,不是一個空字符,這是一個非常不同的事情。

您的宏NULLC不是特別有用。如果你想引用一個空字符,只需使用字面常量'\0'。 (和NULLC是IMHO與NULL太容易混淆。)

另外兩個常數,'\0'0,具有完全相同的類型(int)和值(零)。

(這是無可否認的counterintutive是'\0'具有類型int,而不是char,它是這樣的歷史原因,它基本上沒有什麼關係。在C++中,字符常量是char類型,但你問C.)

+0

+1更爲具體說明:) – 0decimal0

5

它們都具有相同的值0但它們並不意味着同樣的事情。

short somevar = NULL; 

或類似的東西:

(char)NULL - You are casting the value of NULL pointer to character with value 0 
'\0'  - End of string character with value 0 (NUL) 
0   - 32 bit integer with value 0. 

你是因爲地方在你的代碼,你很可能會使用像得到一個警告。

+5

該標準不保證「NULL」被表示爲0,儘管基本上所有的現代系統都這樣做。所以'\ 0'和0是相同的東西(字符文字的類型實際上是int),但是NULL可能不同。 –

2

0'\0'都是整數0(字符文字的類型是int,而不是char),因此它們完全等效。 memset的第二個參數是一個int,從中只會使用低8位。

NULL是不同的野獸。它是一種指針類型,由標準保證與指向真實對象的指針不同。標準是不是說這是通過給它的值0來完成的,儘管它必須比較等於零。此外,它的寬度可能與int不同,因此將它作爲第二個參數傳遞給memset()可能無法編譯。

+0

基本上正確,但措詞不精確。 「整數」是比「int」更通用的術語。你的第一句話似乎混淆了他們。使用'memset'的第二個參數的低位'CHAR_BIT'位;更確切地說,'int'值被轉換爲'unsigned char'。 'NULL'不是「指針類型」;它是一個擴展爲實現定義的空指針常量的宏。指針和int的相對寬度與是否編譯memset時的相關寬度無關;這取決於參數的類型,不是它們的大小 –

+0

NULL的類型是實現定義的(無論是* void *還是某種整數類型),但將它轉換爲'char'總是合法的 - 儘管這樣做沒有意義 –

+0

不,NULL不總是0。'(void *)0'必須計算爲NULL,並且將指針與0進行比較必須與將其與NULL進行比較相同,但NULL不必實際在內部表示爲0,並且實際上確實存在一些使用一個不同的。 Keith,NULL可能是一個'long',並且調用具有很長第二個參數(不投射它)的memset可能會出錯,不是嗎? –

0

在定義NULLC時,您正在從原生指針(64位,可能定義爲(void*)0)到char(8位)轉換NULL。如果你想聲明NULLC,你應該只是做

#define NULLC 0 

NULL(char)做掉。 memset的正式參數是int,而不是char

0
0 = zero of int datatype 
'\0' = (char)0 //null char 
NULL = (void*)0 //null pointer 

看看它們是如何相互連接的。 Gcc經常給出編譯器隱含完成的所有類型轉換的警告。

您正在使用

#define NULLC (char)NULL 
..... 
memset(process_name, NULLC, MAX_LEN + 1); 

等效於:

memset(process_name, (char)NULL, MAX_LEN + 1); 

等效於:

memset(process_name, '\0', MAX_LEN + 1); 

你傳入char數據(即; '\0')作爲第二個參數,其中「無符號int「數據被接受。所以編譯器將它轉換爲unsigned int implicilty,從而給出類型轉換警告。您可以簡單地忽略它或將其更改爲:

memset(process_name, 0, MAX_LEN + 1); 
相關問題