这是我的警告。
warning: passing argument 2 of ‘memset’ makes integer from pointer without a cast
然后我进行了如下更改(将NULL改为0)。
Before Change : memset(key, NULL, KEY_BYTES);
After Change : memset(key, 0, KEY_BYTES);
警告已被解除。
我正在使用Linux和GCC编译器,C语言。
这是正确的操作吗?
这是我的警告。
warning: passing argument 2 of ‘memset’ makes integer from pointer without a cast
Before Change : memset(key, NULL, KEY_BYTES);
After Change : memset(key, 0, KEY_BYTES);
警告已被解除。
我正在使用Linux和GCC编译器,C语言。
这是正确的操作吗?
根据实现方式,C标准库有时将NULL定义为零整数(这将避免您看到的警告),但有时将NULL定义为零强制转换为void指针。后一种实现会引起您看到的警告。
回答您具体的问题,您在这种情况下不应该使用NULL。无论实现如何,NULL都旨在用作空指针,而不是整数零的同义词。如果您想使用memset
将一块内存填充为零,则应将零作为第二个参数传递,而不是NULL。
引用自http://en.wikipedia.org/wiki/Stdlib.h:
NULL
stdlib.h和stddef.h头文件定义了宏NULL,它产生一个null指针常量,并表示一个指针值,保证不指向内存中的有效地址。
变体
NULL可以被定义为等于int零、long int零或零强制转换为void *指针的常量表达式:
#define NULL 0
#define NULL 0L
#define NULL ((void*)0)尽管在C中,空指针常量始终由符号常量0或0强制转换为void指针表示,但这样的指针的实际位表示因系统而异,可能包含一位。
memset
的第二个参数的类型是int
。在C语言中,NULL
是“空指针常量”。根据标准规定:void *
,被称为‘空指针常量’。”NULL
可以定义为(void *)0
或等同形式。如果您将指针转换为整数,则memset
调用是错误的。0
,编译器会为您执行转换。因此,给定类型T
,以下代码将同时将p
和q
设置为null指针:T *p = NULL;
T *q = 0;
此外,针对指针 p
,下列语句等价:
if (p) ...
if (p != NULL) ...
if (p != 0) ...
0
很特殊:在指针上下文中,它会自动转换为null指针常量。而指针则永远不会隐式地转换为整数。任何整数除了0
以外,也永远不会隐式地转换为指针。i
的值为0
,在分配给p
时它也不是一个空指针常量:int i = 0;
int *p = i;
在符合模式下编译时,上述内容会触发警告。
(上述内容有点离题,但我希望它不完全离题。)
是的,它们有相同的效果。编译器必须将NULL视为特殊的NULL指针(而一些更原始的编译器仅仅使用 #define NULL 0
),并且memset的第二个参数是类型为int
的,因此通过将其更改为0,您正在使用空值但满足int要求。
#define NULL 0
不是“更原始的”。这是C++标准的做法,(void)0
甚至在C++中都不允许。在C语言中,(void)0
更常用/更符合标准。 - sbimemset函数的第二个参数应该是一个字符而不是任何指针。在你的第一次调用中,你传递了一个空指针NULL,它在C语言中指向空地址。这就是为什么会出现错误。在第二次调用中,你将0字节分配给了所给定的内存。
在使用memset(key, NULL, KEY_BYTES);
时,NULL是(int零的void*类型转换)即(void*)0。
而且,memset的第二个参数应该是"unsigned int"类型,这就是为什么会显示警告。
根据您使用的编译器不同,它的行为也会有所不同。 使用gcc编译器会发出警告(关于数据类型转换),并将接受给定参数值中最接近的可用值。