1

我们正在将 32 位应用程序从 rhel 5.3 迁移到 6.4

我们在新系统的memset.

(char)NULL在 C 的 memset 中,Do'\0'0all 的意思是一样的吗?

以下代码在新环境中发出警告。

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

5 回答 5

10

尽管它们可能产生相同的结果,但它们的含义并不相同。

(char)NULL将 的值(NULL实现定义的空指针常量)转换为char。的类型NULL可能是int, 或void*, 或其他整数类型。如果它是整数类型,则转换定义明确并产生0. 如果是,则将空指针void*转换为,它具有实现定义的结果(可能但不保证为 0)。char

该宏旨NULL在引用空指针值,而不是空字符,这是非常不同的事情。

您的宏NULLC不是特别有用。如果要引用空字符,只需使用文字常量'\0'。(NULLC恕我直言,太容易与 . 混淆了NULL。)

其他两个常量'\0'0具有完全相同的类型 ( int) 和值(零)。

'\0'(诚​​然,具有 typeint而不是.是违反直觉的char。出于历史原因,这种方式并不重要。在 C++ 中,字符常量是 type char,但您询问了 C。)

于 2013-07-15T22:22:15.510 回答
5

它们都具有相同的值0,但它们的含义不同。

(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.

您收到警告是因为在您的代码中的某处您可能使用了类似的东西:

short somevar = NULL;

或类似的东西。

于 2013-07-15T19:31:45.267 回答
2

0并且'\0'都是整数 0(字符文字的类型是int,不是char),所以它们完全等价。memset 的第二个参数是一个 int,只使用其中的低 8 位。

NULL 是另一种野兽。它是一种指针类型,标准保证与指向真实对象的任何指针不同。标准并没有说这是通过给它值 0 来完成的,尽管它必须比较等于零。此外,它的宽度可能与 不同int,因此将其作为第二个参数传递给memset()可能无法编译。

于 2013-07-15T22:27:33.207 回答
0

在定义 NULLC 时,您正在NULL从本地指针(64 位,可能定义为(void*)0)转换为char(8 位)。如果你想声明 NULLC,你应该这样做

#define NULLC 0

并取消NULLand (char)。的正式论证memsetint,不是char

于 2013-07-15T22:32:04.800 回答
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')作为接受“无符号整数”数据的第二个参数传递。因此编译器将其转换为 unsigned int 隐含,从而给出类型转换警告。您可以简单地忽略它或将其更改为:

memset(process_name, 0, MAX_LEN + 1);
于 2015-05-12T11:10:45.073 回答