我们正在将 32 位应用程序从 rhel 5.3 迁移到 6.4
我们在新系统的memset
.
(char)NULL
在 C 的 memset 中,Do'\0'
和0
all 的意思是一样的吗?
以下代码在新环境中发出警告。
#define NULLC (char)NULL
#define MAX_LEN 11
…
memset(process_name, NULLC, MAX_LEN + 1);
strncpy(process_name, "oreo", MAX_LEN);
尽管它们可能产生相同的结果,但它们的含义并不相同。
(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。)
它们都具有相同的值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;
或类似的东西。
0
并且'\0'
都是整数 0(字符文字的类型是int
,不是char
),所以它们完全等价。memset 的第二个参数是一个 int,只使用其中的低 8 位。
NULL 是另一种野兽。它是一种指针类型,标准保证与指向真实对象的任何指针不同。标准并没有说这是通过给它值 0 来完成的,尽管它必须比较等于零。此外,它的宽度可能与 不同int
,因此将其作为第二个参数传递给memset()
可能无法编译。
在定义 NULLC 时,您正在NULL
从本地指针(64 位,可能定义为(void*)0
)转换为char
(8 位)。如果你想声明 NULLC,你应该这样做
#define NULLC 0
并取消NULL
and (char)
。的正式论证memset
是int
,不是char
。
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);