
Sequence Points, Aliasing & Optimisation
Quote:
>OK, maybe this is a dumb question/FAQ (it's getting a little late) ...
>Supposing I modify a variable via a pointer. Then suppose I reference
>the original variable directly. Assuming I didn't declare the variable
>itself as a volatile, are there any points at which I can rely on
>picking up the updated value, and not an earlier one stashed in a
>register?
The semantic of C are that values are held in objects. Updating an object
through a pointer is just as valid as through a variable name. The
All opdates to objects are complete by the next sequence point.
Quote:
>E.g:
>#include <stdlib.h>
>#include <stdio.h>
>int main(void) {
>int i = 0;
>int *p = &i;
>register int j;
> *p = 1;
> j = i;
> *p = 2;
> j += i;
> fprintf(stdout,"j = %d\n",j);
> return EXIT_SUCCESS;
>}
>I'm assuming (hopefully correctly) that the assignments to i via *p will
>be committed to memory by the next sequence point; that is, not cached
>in a register or optimised out.
When you write to *p the value of that object is changed. Any valid attempt
to read the value of that object after then next sequence point must get
the new value. Registers etc. are an implementation issue. However
whatever an implementation does it must preserve the semantics of the
language.
Quote:
> I guess what I'm concerned about is
>that it might conceivably assume that "i" hasn't been changed during
>execution, and do something "clever" such as assume a value of zero ...
A valid C compiler can't do that. The only time this is possible
is if i is modified by something other than the normal execution of
the program, e.g. in a signal handler. Other possibilities are threads,
shared memory, interrupts, hardware registers etc. but these are all
beyond standard C anyway.
Quote:
>I've tried this on two compilers, and get j=3 in both cases, as would
>obviously be intended. Is there any guarantee that I'll get the
>intended result, or is the above dangerous? If it's safe, then the next
>question is probably moot, but ... if I compare that with, say:
>...
>int i = 0;
>...
>foobar(&i);
>...
>if (i > 0) ...
>where foobar is:
>void foobar(int *n) {
> *n = 1;
>}
>... which appears to be a perfectly legitimate construct. I mean, I'm
>still taking the address of a variable, and modifying it indirectly via
>the resulting pointer, but does the fact that a function call is
>executed change anything with respect to this?
No, it must still work. You should begin to see how using pointers
can in some cases seriously limit a compiler's optimisation options.
--
-----------------------------------------
-----------------------------------------