tags:

views:

281

answers:

5
+2  Q: 

C memset warning

This is my warning.

warning: passing argument 2 of ‘memset’ makes integer from pointer without a cast

Then i changed as follows (make NULL to 0)

Before Change : memset(key, NULL, KEY_BYTES);
After Change : memset(key, 0, KEY_BYTES);

The warning is removed.

i am using linux & gcc compiler,C.

Is it correct action

+1  A: 

Yes, they have the same effect. The compiler must be treating NULL as a special NULL pointer (whereas some more primitive compilers simply #define NULL 0), and the second parameter of memset is of type int, so by changing it to 0 you are using the null value but satisfying the int requirement.

Ricket
`#define NULL 0` isn't "more primitive". It's C++ standard to do so, `(void)0` isn't even allowed in C++. In C, `(void)0` is more used/more std conforming.
sbi
@sbi You're missing an asterisk: (void*)0
Charlie Somerville
@Charlie: Of course. Sorry for that silly error. Otherwise I think I'm right, though.
sbi
+3  A: 

Possibly NULL is defined as ((void*)0). Both versions work correctly, but the second looks better - memset requires a number and not a pointer.

Alex Farber
+10  A: 

Depending on implementation, the C standard library sometimes defines NULL as a zero integer (which would avoid the warning you saw) but sometimes defines NULL as zero cast into a void pointer. The latter implementation causes the warning you saw.

To answer your specific question, you should not be using NULL in this case. Regardless of the implementation, NULL is intended to be used as a null pointer, not a synonym for integer zero. If you want to use memset to fill a block of memory with zeroes, then pass zero as the second argument, not NULL.

Quoting from http://en.wikipedia.org/wiki/Stdlib.h:

NULL

The stdlib.h and stddef.h header files define the macro NULL, which yields a null pointer constant, and represents a pointer value that is guaranteed not to point to a valid address in memory.

Variants

NULL may be defined as a constant expression equal to int zero, long int zero, or zero cast to a void * pointer:

#define NULL 0
#define NULL 0L
#define NULL ((void *) 0)

Although the null pointer constant is always represented in C by the symbolic constant 0 or by 0 cast to a void pointer, the actual bit representation of such a pointer is system-specific and may contain one-bits.

Justin Grant
+2  A: 

The second parameter to memset is of type int. NULL is the null pointer constant in C. According to the standard:

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.

So, NULL may be defined as (void *)0 or equivalent. In such a case, your memset call is wrong because you are converting a pointer to an integer.

The other way is okay: if you use 0 where a null pointer is expected, the compiler will do the conversion for you. So, given a type T, the following sets both p and q to the null pointer:

T *p = NULL;
T *q = 0;

Further, given a pointer p, the following are equivalent:

if (p) ...
if (p != NULL) ...
if (p != 0) ...

This is because 0 is special: in pointer contexts, it is automatically converted to the null pointer constant. A pointer on the other hand, is never converted to an integer implicitly. Any integer other than 0 is also never converted to a pointer implicitly.

Finally, in the code below, even though i has the value 0, it is not a null pointer constant in the assignment to p:

int i = 0;
int *p = i;

The above will trigger a warning when compiled in conformant mode.

(The above is a bit of a digression, but I hope it is not completely off-topic.)

Alok
A: 

memset accepts second argument as a character not any pointer.In your first call,you pass the NULL which is a pointer points to nothing in C.That's why,it gave error.In the second call,you 're assigning 0 bytes to the memory given.