Reputation: 9437
I always thought that C does not accept NULL parameters, until I started learning about pointers. In some programming languages, like python for one, it is possible to pass a NULL parameter as an argument, but in C I always thought this would result in Undefined Behaviour.
My question is just one of curiosity, how can a function, such as this...
waitpid(child_pid, &status, options); //pointer &status
...accept a NULL pointer as parameter without running into Undefined Behaviour, don't NULL pointers simply point to nothing?
Simply put, why is this acceptable in C?
Upvotes: 9
Views: 19719
Reputation: 726809
In some programming languages [...] it is possible to pass a NULL parameter as an argument, but in C I always thought this would result in Undefined Behavior.
Passing a NULL
parameter for a pointer by itself does not result in UB; it's attempting to access the memory pointed to by a pointer set to NULL
that does.
Passing NULL
is a very common practice for situations when something is not specified. The caller is expected to check parameters for NULL
before performing the access. For example, the standard lets you pass NULL
to free
, which makes the function a lot more convenient.
don't
NULL
pointers simply point to nothing?
Yes, they do. But that "nothing" is globally well-known, so using a NULL
lets you communicate the fact that a pointer points to nothing to functions that you call. In other words, the check
if (myPointer == NULL)
is well-defined*, so you can use it to your advantage.
* Unless you use a dangling pointer, i.e. a pointer that you have freed, or a pointer that points to object that went out of scope. You can prevent the first situation from happening by assigning NULL
to every pointer that you free()
, and the second situation by declaring pointers in the scope that has the same or higher level of nesting as the scope of an automatic object to which the pointer is pointing.
Upvotes: 9
Reputation: 126867
Because a function can check if the pointer is NULL and avoid using it. A classic example is a function that returns something as a return value, and can provide some additional information through a pointer parameter. If the caller is not interested in such information (and the callee is prepared for this) the pointer parameter is set to NULL, and the called function won't try to store anything in the location pointed by it.
int divide(int dividend, int divisor, int *remainder=NULL)
{
if(remainder!=NULL)
*remainder=dividend%divisor;
return dividend/divisor;
}
waitpid follows this idiom: if you don't care about the status, you can pass NULL, avoiding a dummy variable.
In general, you can use NULL as a special value to signify that no valid pointer has been passed; another common usage is to say "use a default value" for some pointer parameter.
Notice that this isn't much different from Python: you can't do much on a None without getting an error, but you can always check if a value is None and act accordingly.
Upvotes: 1
Reputation: 918
It all depends on how you deal with NULL. Essentially NULL represents a value of 0, thus if you try to use it as an integer you shouldn't have any problems. BUT keep in mind that NULL is a define to represent invalid memory position (inexistent) and not to be used as an integer!
For pointers, on the other hand, it is important to verify whether the pointer points to a valid address. Usually functions that accept pointers must verify if the value passed is valid, otherwise it'll end up trying to access some invalid memory position and crashing.
Upvotes: 0
Reputation: 124722
void func_with_optional_arg(char *optional)
{
if (optional == NULL) {
// do something differently
}
/* ... */
}
Why would that invoke UB? Dereferencing a NULL
pointer certainly would, but passing one around does not. NULL
is a sentinel value used to determine whether or not a pointer is valid (not that invalid pointers cannot have other values, but we use this one explicitly.) If passing it to a function invoked UB then what would be the point of its existence in the first place?
whereas passing a NULL non-pointer value is not?
There is no such thing as a "NULL non-pointer" in C, so I'm not sure what you mean here.
Upvotes: 4