pointers & order of execution

david.f.prosser dfp at cbnewsl.ATT.COM
Thu Aug 3 01:05:33 AEST 1989


In article <921 at tukki.jyu.fi> tarvaine at tukki.jyu.fi (Tapani Tarvainen) writes:
>
>Consider the following code fragment:
>
>	b = (char *) malloc(n);
>	c = b + x;
>...
>	t = b;
>	b = (char *) realloc(b, m);
>/*1*/	i = b - t;
>	c += i;
>
>The idea is that c keeps pointing to the same thing.
>Is this guaranteed to work?  I think not:
>pointer subtraction assumes the pointers point to
>the same structure, which b and t don't (unless pANS
>says something about realloc in this context?).

The pANS says that this is invalid for a much more fundamental reason:
After a realloc call, the "old" pointer value is indeterminate.  To
make any use of the value causes undefined behavior.  The only valid
means of doing relocation of pointers after a realloc is to compute
the distance from the beginning of the allocated block *before* the
realloc call.

>And indeed, it may fail with Turbo C and probably any 80x86 C with
>large data models.  (The problem came up when porting Gnu grep to
>ms-dos.  See article <920 at tukki.jyu.fi> in gnu.utils.bug for details.)
>
>
>Then how about this:
>
>/*2*/	c = b + (c - t);
>
>Is this guaranteed to work, or is the compiler free to rearrange it as
>
>	c = (b - t) + c;
>
>even though b - t is illegal (and fails)?

This expression fails for the same reason as the first.  However, the pANS
says that the program must behave as if the abstract machine were executing
the code exactly as written.  Thus, only benign rearrangement of expressions
are allowed.  There is no real difference here though, since the behavior is
undefined.

>
>I know it can be done safely like this:
>
>	i = c - t;
>	c = b + i;
>
>which is what I did, but I'd like to know what pANS says about /*2*/.

Assuming this occurs *after* the realloc call, it cannot be done safely
this way.

But your question is whether an expression such as

	int i; char *c, *t, *b;

	c = b + (c - t);

can be rearranged to be

	c += b - t;

by a valid ANSI C compiler.  The answer is "maybe", but only if it makes
no detectable difference to the program.  Writing the expression instead as

	i = c - t; c = b + i;

forces the assignment to i before the assignment to c, but has no real
distinguishable difference from the first form except in regards volatile
objects and interrupts, and so forth.

Dave Prosser	...not an official X3J11 answer...



More information about the Comp.std.c mailing list