printf("%p\n", (void *)0); /* UB, or not? Please explain your answer. */
printf("%p\n", (void *)0);
Collapse
This topic is closed.
X
X
-
infobahnTags: None -
G Fernandes
Re: printf("%p \n", (void *)0);
infobahn wrote:[color=blue]
> printf("%p\n", (void *)0); /* UB, or not? Please explain your answer.[/color]
*/
I don't think there is anything in the standard that makes this UB.
You are not dereferencing a NULL pointer (which is UB) and it's the
value of the poitner (address) that is used here.
-
Walter Roberson
Re: printf("%p \n", (void *)0);
In article <422A3009.D149B 087@btinternet. com>,
infobahn <infobahn@btint ernet.com> wrote:
:printf("%p\n", (void *)0); /* UB, or not? Please explain your answer. */
Depends what you mean by "UB". All that the standard mandates about
%p is that the implimentation will print -something- out, and that
if scanf("%p") is used to read it back in within the same execution
session then the result will compare equal to the original pointer.
-What- is printed is undefined -- it need not even be numeric.
It could print out verses from the Koran... translated into Farsi...
though admittedly you are more likely to get snippets of dialogue
from "Gilligan's Island".
--
Entropy is the logarithm of probability -- Boltzmann
Comment
-
CBFalconer
Re: printf("%p \n", (void *)0);
infobahn wrote:[color=blue]
>
> printf("%p\n", (void *)0); /* UB, or not? Please explain your answer. */[/color]
UB, due to lack of prototype for printf, and appearing outside of
the body of a function.
--
"If you want to post a followup via groups.google.c om, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Comment
-
Keith Thompson
Re: printf("%p \n", (void *)0);
infobahn <infobahn@btint ernet.com> writes:[color=blue]
> printf("%p\n", (void *)0); /* UB, or not? Please explain your answer. */[/color]
Ooh, good catch!
Assuming it appears in a valid context (within a function, and with a
"#include <stdio.h>" in the right place), a strict reading of the
standard could lead to the conclusion that it's undefined behavior.
However, I think it's clear that it's not *intended* to be undefined
behavior, and the standard can (and IMHO should) be read so that it
isn't. (The output is implementation-defined, of course, but that's
not what your asking about.)
C99 7.1.4, "Use of library functions", says:
Each of the following statements applies unless explicitly stated
otherwise in the detailed descriptions that follow: If an argument
to a function has an invalid value (such as a value outside the
domain of the function, or a pointer outside the address space of
the program, or a null pointer, or a pointer to non-modifiable
storage when the corresponding parameter is not const-qualified)
or a type (after promotion) not expected by a function with
variable number of arguments, the behavior is undefined.
C99 7.19.6.1p8, "The fprintf function" (page 279) says:
p The argument shall be a pointer to void. The value of the
pointer is converted to a sequence of printing characters, in
an implementation-defined manner.
Since this doesn't explicitly say that a null pointer is allowed, one
could argue that it's undefined behavior.
The escape clause, I think is that 7.1.4 says "If an argument to a
function has an invalid value (*such as* ... a null pointer ...)". If
I turn my head to one side and squint, I can read this as saying that
a null pointer can be an invalid value, not necessarily that it always
is one.
On the other hand, the same reasoning could imply that strlen(NULL)
doesn't invoke undefined behavior. We have to use common sense to
determine that printf("%p\n", (void*)0)) is ok but strlen(NULL) is not
-- but some people's "common sense" will lead them to conclude that
the latter should always return 0.
Realistically, any implementation won't do anything more exotic that
printing some implementation-defined character string.
Still, I think this calls for a DR.
--
Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Comment
-
aegis
Re: printf("%p \n", (void *)0);
Keith Thompson wrote:[color=blue]
> infobahn <infobahn@btint ernet.com> writes:[color=green]
> > printf("%p\n", (void *)0); /* UB, or not? Please explain your[/color][/color]
answer. */[color=blue]
>
> Ooh, good catch!
>
> Assuming it appears in a valid context (within a function, and with a
> "#include <stdio.h>" in the right place), a strict reading of the
> standard could lead to the conclusion that it's undefined behavior.
> However, I think it's clear that it's not *intended* to be undefined
> behavior, and the standard can (and IMHO should) be read so that it
> isn't. (The output is implementation-defined, of course, but that's
> not what your asking about.)
>
> C99 7.1.4, "Use of library functions", says:
>
> Each of the following statements applies unless explicitly stated
> otherwise in the detailed descriptions that follow: If an[/color]
argument[color=blue]
> to a function has an invalid value (such as a value outside the
> domain of the function, or a pointer outside the address space of
> the program, or a null pointer, or a pointer to non-modifiable
> storage when the corresponding parameter is not const-qualified)
> or a type (after promotion) not expected by a function with
> variable number of arguments, the behavior is undefined.
>
> C99 7.19.6.1p8, "The fprintf function" (page 279) says:
>
> p The argument shall be a pointer to void. The value of the
> pointer is converted to a sequence of printing characters, in
> an implementation-defined manner.
>
> Since this doesn't explicitly say that a null pointer is allowed, one
> could argue that it's undefined behavior.
>[/color]
Is (void *)0 a null pointer? I thought it was a null pointer constant.
[color=blue]
> The escape clause, I think is that 7.1.4 says "If an argument to a
> function has an invalid value (*such as* ... a null pointer ...)".[/color]
If[color=blue]
> I turn my head to one side and squint, I can read this as saying that
> a null pointer can be an invalid value, not necessarily that it[/color]
always[color=blue]
> is one.[/color]
Yes. I think so too. But the example involves a null pointer constant.
[color=blue]
>
> On the other hand, the same reasoning could imply that strlen(NULL)
> doesn't invoke undefined behavior. We have to use common sense to[/color]
strlen expects a valid string. NULL is no such thing.
[color=blue]
> determine that printf("%p\n", (void*)0)) is ok but strlen(NULL) is[/color]
not[color=blue]
> -- but some people's "common sense" will lead them to conclude that
> the latter should always return 0.[/color]
No. Because a null pointer constant is different from a null pointer.
char *p = NULL;
'p' is a null pointer.
But (void *)0 is a null pointer constant in the example above.
[color=blue]
>
> Realistically, any implementation won't do anything more exotic that
> printing some implementation-defined character string.
>
> Still, I think this calls for a DR.
>[/color]
I don't.
[color=blue]
> --
> Keith Thompson (The_Other_Keit h) kst-u@mib.org[/color]
<http://www.ghoti.net/~kst>[color=blue]
> San Diego Supercomputer Center <*>[/color]
<http://users.sdsc.edu/~kst>[color=blue]
> We must do something. This is something. Therefore, we must do[/color]
this.
--
aegis
Comment
-
Peter Nilsson
Re: printf("%p \n", (void *)0);
> infobahn <infobahn@btint ernet.com> writes:[color=blue][color=green]
> > printf("%p\n", (void *)0); /* UB, or not? Please explain your[/color][/color]
answer. */
What is _your_ theory? In other words, what leads you to question this
in the first place?
Keith Thompson wrote:[color=blue]
> Ooh, good catch!
>
> Assuming it appears in a valid context (within a function, and with a
> "#include <stdio.h>" in the right place), a strict reading of the
> standard could lead to the conclusion that it's undefined behavior.[/color]
Why?
[color=blue]
> C99 7.1.4, "Use of library functions", says:
>
> Each of the following statements applies unless explicitly stated
> otherwise in the detailed descriptions that follow: If an[/color]
argument[color=blue]
> to a function has an invalid value (such as a value outside the
> domain of the function, or a pointer outside the address space of
> the program, or a null pointer, or a pointer to non-modifiable
> storage when the corresponding parameter is not const-qualified)
> or a type (after promotion) not expected by a function with
> variable number of arguments, the behavior is undefined.
>
> C99 7.19.6.1p8, "The fprintf function" (page 279) says:
>
> p The argument shall be a pointer to void. The value of the
> pointer is converted to a sequence of printing characters, in
> an implementation-defined manner.
>
> Since this doesn't explicitly say that a null pointer is allowed, one
> could argue that it's undefined behavior.[/color]
Since when was a pointer not allowed to be a null pointer in it's own
right?
[color=blue]
> The escape clause, I think is that 7.1.4 says "If an argument to a
> function has an invalid value (*such as* ... a null pointer ...)".[/color]
If[color=blue]
> I turn my head to one side and squint, I can read this as saying that
> a null pointer can be an invalid value, not necessarily that it[/color]
always[color=blue]
> is one.
>
> On the other hand, the same reasoning could imply that strlen(NULL)
> doesn't invoke undefined behavior.[/color]
Since strlen 'computes the length of _a string_', it's clear that a
null pointer is invalid.
[color=blue]
> Still, I think this calls for a DR.[/color]
I say nay. ;)
--
Peter
Comment
-
Peter Nilsson
Re: printf("%p \n", (void *)0);
aegis wrote:[color=blue]
>
> Is (void *)0 a null pointer? I thought it was a null pointer[/color]
constant.
It's both, by definition.
--
Peter
Comment
-
Peter Nilsson
Re: printf("%p \n", (void *)0);
CBFalconer wrote:[color=blue]
> infobahn wrote:[color=green]
> >
> > printf("%p\n", (void *)0); /* UB, or not? Please explain your[/color][/color]
answer. */[color=blue]
>
> UB, due to lack of prototype for printf, and appearing outside of
> the body of a function.[/color]
I'm not convinced there's anything worth discussing in the OP's post,
but your reply is "...100% correct and 0% helpful."
--
Peter
Comment
-
infobahn
Re: printf("%p \n", (void *)0);
[I haven't seen Keith's reply to my original question, except in
this reply-to-reply.]
aegis wrote:[color=blue]
>
> Keith Thompson wrote:[color=green]
> > infobahn <infobahn@btint ernet.com> writes:[color=darkred]
> > > printf("%p\n", (void *)0); /* UB, or not? Please explain your[/color][/color]
> answer. */[color=green]
> >
> > Ooh, good catch!
> >
> > Assuming it appears in a valid context (within a function, and with a
> > "#include <stdio.h>" in the right place), a strict reading of the
> > standard could lead to the conclusion that it's undefined behavior.[/color][/color]
That's part of what worries me.
[color=blue][color=green]
> > However, I think it's clear that it's not *intended* to be undefined
> > behavior, and the standard can (and IMHO should) be read so that it
> > isn't.[/color][/color]
And that's the rest of what worries me.
[color=blue][color=green]
> > (The output is implementation-defined, of course, but that's
> > not what your asking about.)[/color][/color]
Correct.
[color=blue][color=green]
> > C99 7.1.4, "Use of library functions", says:[/color][/color]
Yes, that's part of my concern.
[color=blue][color=green]
> > C99 7.19.6.1p8, "The fprintf function" (page 279) says:[/color][/color]
And that's the other part.
[color=blue]
> Is (void *)0 a null pointer? I thought it was a null pointer constant.[/color]
If it worries you, pretend I said:
#include <stdio.h>
int main(void)
{
int *p = NULL;
printf("%p\n", (void *)p);
return 0;
}
[color=blue][color=green]
> > The escape clause, I think is that 7.1.4 says "If an argument to a
> > function has an invalid value (*such as* ... a null pointer ...)".
> > If I turn my head to one side and squint, I can read this as saying
> > that a null pointer can be an invalid value, not necessarily that
> > it always is one.[/color][/color]
The problem I have with this rationalisation is that it sounds too
much like rationalisation . I can hear Herbert Schildt saying "It
doesn't say you can't!", and that worries me.
[color=blue][color=green]
> > Realistically, any implementation won't do anything more exotic that
> > printing some implementation-defined character string.
> >
> > Still, I think this calls for a DR.[/color][/color]
Or at least a clarification from the Great Powers, complete with C&V.
Comment
-
Keith Thompson
Re: printf("%p \n", (void *)0);
"aegis" <aegis@mad.scie ntist.com> writes:[color=blue]
> Keith Thompson wrote:[color=green]
>> infobahn <infobahn@btint ernet.com> writes:[color=darkred]
>> > printf("%p\n", (void *)0); /* UB, or not? Please explain your[/color][/color]
> answer. */[/color]
[snip]
[color=blue]
> Is (void *)0 a null pointer? I thought it was a null pointer constant.[/color]
Yes, it's a null pointer constant, which is a source construct. A
null pointer is a value that exists at run time. In the function call
above, a null pointer is passed as an argument to printf. (That's
what null pointer constants are for, after all.)
[color=blue][color=green]
>> The escape clause, I think is that 7.1.4 says "If an argument to a
>> function has an invalid value (*such as* ... a null pointer
>> ...)". If I turn my head to one side and squint, I can read this as
>> saying that a null pointer can be an invalid value, not necessarily
>> that it always is one.[/color]
>
> Yes. I think so too. But the example involves a null pointer constant.[/color]
Which results in a null pointer at run time.
[color=blue][color=green]
>> On the other hand, the same reasoning could imply that strlen(NULL)
>> doesn't invoke undefined behavior. We have to use common sense to[/color]
>
> strlen expects a valid string. NULL is no such thing.[/color]
One could argue that printf("%p", ...) expects a valid pointer, and
that NULL is not a valid pointer. The wording of the standard doesn't
exclude that interpretation.
[color=blue][color=green]
>> determine that printf("%p\n", (void*)0)) is ok but strlen(NULL) is[/color]
> not[color=green]
>> -- but some people's "common sense" will lead them to conclude that
>> the latter should always return 0.[/color]
>
> No. Because a null pointer constant is different from a null pointer.[/color]
That has nothing to do with it.
[snip]
--
Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Comment
-
Keith Thompson
Re: printf("%p \n", (void *)0);
infobahn <infobahn@btint ernet.com> writes:[color=blue]
> [I haven't seen Keith's reply to my original question, except in
> this reply-to-reply.][/color]
Perhaps because aegis cross-posted his reply to comp.lang.c and
comp.std.c (the original article was posted only to comp.lang.c).
--
Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Comment
-
infobahn
Re: printf("%p \n", (void *)0);
Peter Nilsson wrote:[color=blue]
>
> CBFalconer wrote:[color=green]
> > infobahn wrote:[color=darkred]
> > >
> > > printf("%p\n", (void *)0); /* UB, or not? Please explain your[/color][/color]
> answer. */[color=green]
> >
> > UB, due to lack of prototype for printf, and appearing outside of
> > the body of a function.[/color][/color]
(Cute.)
[color=blue]
>
> I'm not convinced there's anything worth discussing in the OP's post,[/color]
The point is this: I have written a routine which takes T **p,
frees the memory pointed to by *p, and sets *p to NULL. In a
demo driver routine, I am trying to show that the pointer is now
NULL, using printf. When gcc showed me "(nil)" instead of something
more - well - more pointery!, I was reminded of the way it responds
to a %s/NULL match, and this concerned me, since I know perfectly
well that %s/NULL is undefined, so I was naturally concerned to
know whether %p/NULL is undefined too. It may be that the goal of
avoiding undefined behaviour is not worth discussing in comp.lang.c
but, if that is the case, why do we spend so much time discussing
precisely that? :-)
[color=blue]
> but [CBFalconer's] reply is "...100% correct and 0% helpful."[/color]
Indeed. I haven't seen his reply except as quoted by your own, but
it seems a rather strange reply to make. I expected better of him.
Comment
-
pete
Re: printf("%p \n", (void *)0);
Keith Thompson wrote:
[color=blue]
> One could argue that printf("%p", ...) expects a valid pointer, and
> that NULL is not a valid pointer. The wording of the standard doesn't
> exclude that interpretation.[/color]
Whether or not NULL is an invalid pointer, depends on context.
free(NULL) is defined.
You can't just say that NULL is an invalid pointer,
without saying invalid for what purpose.
An indeterminate pointer, on the other hand, is just an invalid pointer.
--
pete
Comment
-
CBFalconer
Re: printf("%p \n", (void *)0);
infobahn wrote:[color=blue]
> Peter Nilsson wrote:[color=green]
>> CBFalconer wrote:[color=darkred]
>>> infobahn wrote:
>>>>
>>>> printf("%p\n", (void *)0); /* UB, or not? Please explain your
>>>> answer. */
>>>
>>> UB, due to lack of prototype for printf, and appearing outside of
>>> the body of a function.[/color][/color]
>
> (Cute.)
>[color=green]
>>
>> I'm not convinced there's anything worth discussing in the OP's post,[/color]
>
> The point is this: I have written a routine which takes T **p,
> frees the memory pointed to by *p, and sets *p to NULL. In a
> demo driver routine, I am trying to show that the pointer is now
> NULL, using printf. When gcc showed me "(nil)" instead of something
> more - well - more pointery!, I was reminded of the way it responds
> to a %s/NULL match, and this concerned me, since I know perfectly
> well that %s/NULL is undefined, so I was naturally concerned to
> know whether %p/NULL is undefined too. It may be that the goal of
> avoiding undefined behaviour is not worth discussing in comp.lang.c
> but, if that is the case, why do we spend so much time discussing
> precisely that? :-)
>[color=green]
>> but [CBFalconer's] reply is "...100% correct and 0% helpful."[/color]
>
> Indeed. I haven't seen his reply except as quoted by your own, but
> it seems a rather strange reply to make. I expected better of him.[/color]
Well, I expected better of infobahn :-) As far as the statement
(assuming a proper environment for it) is concerned, printf is
supposed to dump out a representation of a pointer value. NULL is
a suitable value for a pointer. (void *)0 is a means of generating
that NULL value. I see no reason for any implementor to
distinguish it, dereference it, or to criticize its ancestry, so I
should not expect any problems from the snippet. If the standard
does allow problems to arise I consider that a defect in the
standard. And "(nil)" is a representation of a NULL pointer
value. Various gcc oriented printf packages do this in a variety
of situations, which is probably superior to blowing up the barn
door and releasing all the differently colored horses.
--
"If you want to post a followup via groups.google.c om, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Comment
Comment