2011/10/26 Michael Matz <m...@suse.de>: > Hi, > > On Wed, 26 Oct 2011, Kai Tietz wrote: > >> >> > int f(char *i, int j) >> >> > { >> >> > if (*i && j!=2) >> >> > return *i; >> >> > else >> >> > return j; >> >> > } >> >> >> >> the case can be produced quite easily. >> >> extern int global = 0; >> >> .... >> if (*a && global) ... > > See? You had to change the program to prove the transformation to be > invalid. But my point was that the function we discuss about was exactly > as above. It didn't have globals, or two loads, or a volatile, or > anything else you can come up with where the transformation would be > detectable (and hence invalid). I claim that you can't construct a > program that can distinguish between this function: > > int f(char *i, int j) > { > if (*i && j!=2) > return *i; > else > return j; > } > > and this one: > > int f(char *i, int j) > { > if (*i & j!=2) > return *i; > else > return j; > } > > And if you can't construct such a program, then the initial transformation > before the fold-const.c change _for this specific situation_ was correct. > > > Ciao, > Michael.
well, if such a function is used as inline and we know for it that j has value != 2, then we have here a big difference. For your first example, we still have to do the memory access to *i, even if we are not interested in result. See here point 4 of 5.1.2.3 of C-spec. For your second sample we don't need to do that, as the & itself is no sequence-point and so we can eliminate the *i access without breaking anything. Regards, Kai