Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!csd4.milw.wisc.edu!bionet!apple!rutgers!dptg!att!cbnewsl!dfp From: dfp@cbnewsl.ATT.COM (david.f.prosser) Newsgroups: comp.std.c Subject: Re: pointers & order of execution Keywords: pointer subtraction, order of execution, realloc Message-ID: <1347@cbnewsl.ATT.COM> Date: 2 Aug 89 15:05:33 GMT References: <920@tukki.jyu.fi> <921@tukki.jyu.fi> Reply-To: dfp@cbnewsl.ATT.COM (david.f.prosser) Organization: AT&T Bell Laboratories Lines: 77 In article <921@tukki.jyu.fi> tarvaine@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@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...