Is this legal ?

K

K.M Jr

Hi group,

I want you to tell me if the following code is legal as per Standard.

void foo(int *p)
{

}

int main(void)
{
foo(NULL);
}

I thought that even copying NULL pointers was a cause of Undefined
Behavior. Am I mistaken ?

Thanks.
 
J

Joona I Palaste

K.M Jr said:
Hi group,
I want you to tell me if the following code is legal as per Standard.
void foo(int *p)
{

int main(void)
{
foo(NULL);
}
I thought that even copying NULL pointers was a cause of Undefined
Behavior. Am I mistaken ?

You are mistaken. Using the value of a NULL pointer is perfectly safe,
as long as you don't try to indirect through the value.
 
M

Mabden

K.M Jr said:
Hi group,

I want you to tell me if the following code is legal as per Standard.

void foo(int *p)
{

}

int main(void)
{
foo(NULL);
}

I thought that even copying NULL pointers was a cause of Undefined
Behavior. Am I mistaken ?

That's fine, but foo() should have a check like this, since you can't
use p if it's NULL:

void foo(int *p)
{
if (p == NULL) return;
}
 
J

Joona I Palaste

That's fine, but foo() should have a check like this, since you can't
use p if it's NULL:
void foo(int *p)
{
if (p == NULL) return;
}

What do you mean "you can't use p if it's NULL"? Using the value of p is
perfectly fine. Perhaps you mean "you can't use *p if p is NULL", which
is entirely true.
 
M

Method Man

K.M Jr said:
Hi group,

I want you to tell me if the following code is legal as per Standard.

void foo(int *p)
{

}

int main(void)
{
foo(NULL);
}

I thought that even copying NULL pointers was a cause of Undefined
Behavior. Am I mistaken ?

Copying NULL pointers is not only legal, but it's done _very_ often. To
assure yourself, have a look at any data structure algorithms for strings,
linked lists, trees, etc.
 
C

CBFalconer

K.M Jr said:
I want you to tell me if the following code is legal as per Standard.

void foo(int *p)
{
}

int main(void)
{
foo(NULL);
}

Almost. It is missing a "return 0" at the end of main.
 
M

Michael Mair

Hi
Almost. It is missing a "return 0" at the end of main.

With C99, this is not necessary for main() (and only main()) --
but I think this is a braindead exception...


Cheers
Michael
 
C

Chris Dollin

Mabden said:
That's fine, but foo() should have a check like this, since you can't
use p if it's NULL:

void foo(int *p)
{
if (p == NULL) return;
}

Utter rubbish.

You *can* use `p` if it's NULL. You can, for example, compare it with a
pointer, pass it as a parameter, store it into a data structure, or return
it as a result. What you *cannot* do [1] is dereference it. In the OPs
example, they ignored it - doesn't look like that needs a check to me.

If you want to dereference it, then you have to decide what to do about
null pointers. Broadly speaking I see three choices:

(a) Declare that this function is undefined if p == 0. Any passing of
null is a user error. You don't need to check for null, since any
dereferencing gets you UB, and that's what you declared, but you
*can* check, and do whatever you like - eg log an error and exit,
log an error and don't exit, exploit some system-dependant exception
handler, whatever.

(b) Declare that p == 0 is illegal and define the error behaviour - such
as having an error code which takes distinct values on failure or
success, and performing the check. Or calling some error-handling
function ditto. Hard to do cleanly in the large.

(c) Declare that p == 0 is legal and has some special-case behaviour,
put in the appropriate check & code. EG one might (unsoundly, in
my view) decide that the string-length of (char *)0 was 0.

Saying the the only valid choice is (b) [and implying, albeit weakly,
that the recovery behaviour is "do nothing"] is ... unwise.

[My preferred choice is (a), if p doesn't express some notion of
"optional thingy", and (c) if it does, and (b) only if the other
two don't work. But I suspect that the weighting is very context-
sensitive.]

[1] If you prefer, you *can* do it, but to do so opens the way to demons,
so don't.
 
C

Christopher Benson-Manica

Joona I Palaste said:
You are mistaken. Using the value of a NULL pointer is perfectly safe,
as long as you don't try to indirect through the value.
^^^^^^^^^^^^^^^^^^^^^^^^^^
Is that semantically identical to "dereference the pointer"?
 
D

Dan Pop

In said:
^^^^^^^^^^^^^^^^^^^^^^^^^^
Is that semantically identical to "dereference the pointer"?

Note that "dereference" is programmer's jargon (used only once in C99,
in a footnote). The official name of the unary * operator is the
indirection operator.

Dan
 
D

Dan Pop

In said:
You are mistaken. Using the value of a NULL pointer is perfectly safe,
as long as you don't try to indirect through the value.

First, it is spelled "null pointer". Not only there is no point in
capitalising "null", it is even misleading. NULL has a very precisely
defined meaning in a C context.

There are more restrictions WRT the usage of null pointers. All you can
with them is copy their value and compare it for equality with other
pointers. Indirection, arithmetic and relational operators are
prohibited (undefined behaviour) on null pointers (despite typical
implementations of the offsetof macro).

Dan
 
D

Dan Pop

In said:
I want you to tell me if the following code is legal as per Standard.

void foo(int *p)
{

}

int main(void)
{
foo(NULL);
}

I thought that even copying NULL pointers was a cause of Undefined
Behavior. Am I mistaken ?

fflush(NULL), free(NULL), time(NULL) and a few others are explicitly
blessed by the C standard. There is nothing wrong with passing a null
pointer to a function, *if* the function is prepared to receive such a
pointer. Since your function simply ignores its parameter, passing a
null pointer to it is perfectly OK.

Dan
 
J

Joona I Palaste

Utter rubbish.
You *can* use `p` if it's NULL. You can, for example, compare it with a
pointer, pass it as a parameter, store it into a data structure, or return
it as a result. What you *cannot* do [1] is dereference it. In the OPs
example, they ignored it - doesn't look like that needs a check to me.

In fact, as I realised after replying to Mabden's post, he *is* using p
in the above code.
 
M

Mabden

Joona I Palaste said:
What do you mean "you can't use p if it's NULL"? Using the value of p is
perfectly fine. Perhaps you mean "you can't use *p if p is NULL", which
is entirely true.

Oops, you're right, I meant "use p" as in put something in it or take
anything out, so I should have said *p. You can, of course, pass it
around all you want or put it somewhere.

I guess the flames are about to begin, anyone got some gasoline to put
them out with?
 
D

Dave Thompson

On 12 Oct 2004 04:06:14 -0700, (e-mail address removed) (K.M Jr)
wrote:
I thought that even copying NULL pointers was a cause of Undefined
Behavior. Am I mistaken ?
It is not and you are mistaken, as others have answered. You might
have been confusing this with something else:

What _is_ UB is fetching, copying, passing, etc., as well as
dereferencing, an _indeterminate_ pointer value, which includes one to
space that has been free'd or otherwise become deallocated.

But a null pointer is not indeterminate; it is a value provided (in
effect reserved) by the implementation that is reliably readable and
writable and reliably not equal to any pointer to a valid object (or
for a pointer-to-function type, any pointer to actual function).

- David.Thompson1 at worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top