Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Undefined behaviour question

Reply
Thread Tools

Undefined behaviour question

 
 
Joona I Palaste
Guest
Posts: n/a
 
      12-16-2003
We all know that this:

void *p;
if (p=malloc(1)) {
free(p);
p;
}

causes undefined behaviour if malloc() succeeds. But what about this?

void *p;
if (p=malloc(1)) {
free(p);
&p;
}

I *think* this is perfectly safe and defined behaviour but as I have
not read the standard I am not sure.

--
/-- Joona Palaste ((E-Mail Removed)) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"O pointy birds, O pointy-pointy. Anoint my head, anointy-nointy."
- Dr. Michael Hfuhruhurr
 
Reply With Quote
 
 
 
 
E. Robert Tisdale
Guest
Posts: n/a
 
      12-16-2003
Joona I Palaste wrote:

> We all know that this:
>
> void *p = malloc(1);
> if (NULL != p) {
> free(p);
> p;
> }
>
> causes undefined behavior if malloc() succeeds. But what about this?
>
> void *p = malloc(1);
> if (NULL != p) {
> free(p);
> &p;
> }
>
> I *think* this is perfectly safe and defined behavior
> but, as I have not read the standard, I am not sure.


It is safe.
Pointer p no longer points to a valid object after free(p)
but p is still a valid pointer object
so a pointer to p is a valid pointer object as well.

 
Reply With Quote
 
 
 
 
Christian Bau
Guest
Posts: n/a
 
      12-16-2003
In article <brns0u$f9v$(E-Mail Removed)>,
Joona I Palaste <(E-Mail Removed)> wrote:

> We all know that this:
>
> void *p;
> if (p=malloc(1)) {
> free(p);
> p;
> }
>
> causes undefined behaviour if malloc() succeeds. But what about this?
>
> void *p;
> if (p=malloc(1)) {
> free(p);
> &p;
> }
>
> I *think* this is perfectly safe and defined behaviour but as I have
> not read the standard I am not sure.


Of course it is perfectly safe. All you do is taking the address of an
existing object. The fact that the object contains nonsense doesn't
cause any problem when you take its address. You might as well ask
whether

void *p;
if (p = malloc (1)) { free (p); p = NULL; }

causes problems. After all, you are assigning NULL to a variable
containing an undefined value.
 
Reply With Quote
 
nrk
Guest
Posts: n/a
 
      12-16-2003
Joona I Palaste wrote:

> We all know that this:
>
> void *p;
> if (p=malloc(1)) {
> free(p);
> p;
> }
>
> causes undefined behaviour if malloc() succeeds. But what about this?
>
> void *p;
> if (p=malloc(1)) {
> free(p);
> &p;
> }
>
> I *think* this is perfectly safe and defined behaviour but as I have
> not read the standard I am not sure.
>


int i;
int *p;

p = &i;

is that safe? does that answer your question?

-nrk.

--
Remove devnull for email
 
Reply With Quote
 
Old Wolf
Guest
Posts: n/a
 
      12-17-2003
> We all know that this:
>
> void *p;
> if (p=malloc(1)) {
> free(p);
> p;
> }
>
> causes undefined behaviour if malloc() succeeds.


Call me Mr. Deer-in-Headlights, but I'd always been taught that
p;
is a no-op.

Furthermore, how about:

if (p=malloc(1)) {
int x = (int)p;
free(p);
x;
}

Casting a pointer to an int is implementation-defined (but not undefined), isn't it?

There does not seem to be much difference between the above, and
if (p=malloc(1)) {
free(p);
int x = (int)p;
x;
}

My rationale: the reason it's undefined to use a pointer value (without
dereferencing) is for systems where loading such a value to a memory
access register causes an exception. However, if we are just converting to
int, that register would not have to be used. Since the int cast is
implementation-defined, the implementation could always do this
without doing anything undefined.
 
Reply With Quote
 
Ben Pfaff
Guest
Posts: n/a
 
      12-17-2003
http://www.velocityreviews.com/forums/(E-Mail Removed) (Old Wolf) writes:

> > We all know that this:
> >
> > void *p;
> > if (p=malloc(1)) {
> > free(p);
> > p;
> > }
> >
> > causes undefined behaviour if malloc() succeeds.

>
> Call me Mr. Deer-in-Headlights, but I'd always been taught that
> p;
> is a no-op.


It's not a no-op from the viewpoint of the standard. Rather, it
calculates the value of variable `p'. Because the value of
variable `p' is indeterminate (see C99 6.2.4#2) and thus may be a
trap representation (see C99 3.17.2), that expression invokes
undefined behavior.

> Furthermore, how about:
>
> if (p=malloc(1)) {
> int x = (int)p;
> free(p);
> x;
> }


No pointer is involved, so if the conversion `(int) p' produced
a value that is not a trap representation, it is still not a trap
representation after the free().

> Casting a pointer to an int is implementation-defined (but not
> undefined), isn't it?


Not necessarily, see C99 6.3.2.3#6:

If the result cannot be represented in the integer type, the
behavior is undefined.

> There does not seem to be much difference between the above, and
> if (p=malloc(1)) {
> free(p);
> int x = (int)p;
> x;
> }


That's undefined too, because the value of `p' is still being
accessed. You could access the bytes in `p' through a character
pointer if you like, though.

> My rationale: the reason it's undefined to use a pointer value (without
> dereferencing) is for systems where loading such a value to a memory
> access register causes an exception.


That's a reasonable reason.

> However, if we are just converting to int, that register would
> not have to be used.


But it's not required not to be used. Behavior is still
undefined.

> Since the int cast is implementation-defined, the
> implementation could always do this without doing anything
> undefined.


--
"Welcome to the wonderful world of undefined behavior, where the demons
are nasal and the DeathStation users are nervous." --Daniel Fox
 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      12-17-2003
Old Wolf wrote:

>> We all know that this:
>>
>> void *p;
>> if (p=malloc(1)) {
>> free(p);
>> p;
>> }
>>
>> causes undefined behaviour if malloc() succeeds.

>
> Call me Mr. Deer-in-Headlights, but I'd always been taught that
> p;
> is a no-op.


In abstract terms, p is evaluated, and then that value is discarded. Whilst
any compiler /may/ optimise it out, it isn't /required/ to. Joona is right;
the behaviour is undefined.


>
> Furthermore, how about:
>
> if (p=malloc(1)) {
> int x = (int)p;
> free(p);
> x;
> }
>
> Casting a pointer to an int is implementation-defined (but not undefined),
> isn't it?


Yes. But in this case, all you're doing is giving x a valid (albeit
implementation-defined) value. It /looks/ very similar to the first case,
but in fact it isn't.

>
> There does not seem to be much difference between the above, and
> if (p=malloc(1)) {
> free(p);
> int x = (int)p;
> x;
> }


Oh, there's a world of difference. This one (quite apart from not even
compiling on C89) exhibits undefined behaviour in line 3, because of the
evaluation of p.

>
> My rationale: the reason it's undefined to use a pointer value (without
> dereferencing) is for systems where loading such a value to a memory
> access register causes an exception. However, if we are just converting to
> int, that register would not have to be used.


I can find no such guarantee in the Standard.

> Since the int cast is
> implementation-defined, the implementation could always do this
> without doing anything undefined.


A cast is a process, taking a value as input. In getting the value for input
to the casting process, you invoke undefined behaviour, so the cast is way
too late.

--
Richard Heathfield : (E-Mail Removed)
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      12-17-2003
Joona I Palaste wrote:

> We all know that this:
>
> void *p;
> if (p=malloc(1)) {
> free(p);
> p;
> }
>
> causes undefined behaviour if malloc() succeeds.


Correct.

> But what about this?
>
> void *p;
> if (p=malloc(1)) {
> free(p);
> &p;
> }
>
> I *think* this is perfectly safe and defined behaviour but as I have
> not read the standard I am not sure.


It is. You should. If you did, then you would be.

Probably.

--
Richard Heathfield : (E-Mail Removed)
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
 
Reply With Quote
 
Jarno A Wuolijoki
Guest
Posts: n/a
 
      12-17-2003
On 16 Dec 2003, Joona I Palaste wrote:

> causes undefined behaviour if malloc() succeeds. But what about this?
>
> void *p;
> if (p=malloc(1)) {
> free(p);
> &p;
> }
>
> I *think* this is perfectly safe and defined behaviour but as I have
> not read the standard I am not sure.


Obviously:

void reincarnate(void **p) { *p=malloc(1); }
void test(void) {
void *p;
if (p=malloc(1)) {
free(p);
reincarnate(&p)
}
}

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
typeof x == 'undefined' or x == undefined? -Lost Javascript 13 01-31-2007 12:04 AM
undefined vs. undefined (was: new Array() vs []) VK Javascript 45 09-12-2006 05:26 PM
Undefined behaviour marbac C++ 48 07-20-2004 10:48 PM
undefined behavior or not undefined behavior? That is the question Mantorok Redgormor C Programming 70 02-17-2004 02:46 PM
undefined behaviour Dan Cernat C++ 1 11-11-2003 04:49 PM



Advertisments