Maestro
Maestro

Reputation: 9518

Pointer from integer without a cast

When I call a function that expects a pointer, and I pass in a value, I get this warning, and I like that.

But when the value happens to be a literal '0', I don't get the warning. I think this is because C think it's null-pointer, and not a value. Is there any way to still get warnings for 0-literals, because I already had some bugs because of it.

Upvotes: 7

Views: 493

Answers (5)

user529758
user529758

Reputation:

Is there any way to still get warnings for 0-literals

I don't know about one, an anyway you don't want that. The constant numeric value 0, when assigned to a pointer, is implicitly treated as NULL without casting it to a pointer type.

Upvotes: 0

Michael Burr
Michael Burr

Reputation: 340516

GCC supports a nonnull attribute on function parameters that can do what you want (as long as the -Wnonnull warning option is enabled):

void* foo( int* cannot_be_null)  __attribute((nonnull (1))) ;


int main(int argc, char *argv[])
{
    int x;
    foo(&x);

    foo(0);  // line 13 - generates a -Wnonnull warning

    return 0;
}

When compiled using gcc -c -Wnonnull test.c I get:

test.c: In function 'main':
test.c:13:5: warning: null argument where non-null required (argument 1) [-Wnonnull]

You can force this to be an error with -Werror=nonnull.

Note that this warning is only thrown when the null pointer literal (another name for 0) is used - the following code doesn't trigger the warning:

int* p = NULL;
foo(p);

Upvotes: 5

sr01853
sr01853

Reputation: 6121

This question is similar to the question. Should I use symbolic names like TRUE and FALSE for Boolean constants, or plain 1 and 0?

C programmers must understand that NULL and 0 are interchangeable in pointer contexts, and that an uncast 0 is perfectly acceptable. Any usage of NULL (as opposed to 0) should be considered a gentle reminder that a pointer is involved; programmers should not depend on it (either for their own understanding or the compiler's) for distinguishing pointer 0's from integer 0's.

It is only in pointer contexts that NULL and 0 are equivalent. NULL should not be used when another kind of 0 is required, even though it might work, because doing so sends the wrong stylistic message. (Furthermore, ANSI allows the definition of NULL to be ((void *)0), which will not work at all in non-pointer contexts.) In particular, do not use NULL when the ASCII null character (NUL) is desired. Provide your own definition

#define NUL '\0'

if you must.

This information is from this link

Upvotes: 0

CaffeinePwrdAl
CaffeinePwrdAl

Reputation: 31

I think conversion to null probably fairly intrinsic to the compiler - It should be easy however to statically check for these cases as they are fairly unique.

If you are expecting to pass null and not (int)0, use an explicit NULL enum or define, and then anything matching the pattern YourFunction(0); (allowing for white space) is definitely invalid. Grep could be used quite easily for this if you want to go low-tech. Various lint tools might be able to do this as Fabien suggested.

I always try to remember when coding that if you can, make wrong things look as wrong as possible, that way you can detect them all the more easily.

Upvotes: 0

Fabien
Fabien

Reputation: 13456

Not with a raw C compiler unfortunately. You should try a lint tool, as splint, that might help you about this (I'm not sure, though).

Upvotes: 1

Related Questions