Jos Bergervoet <
jos.ber...@xs4all.nl> wrote:
> On 4/29/2014 10:04 AM, Richard Maine wrote:
> > Jos Bergervoet<
jos.ber...@xs4all.nl> wrote:
> >> On 4/29/2014 5:21 AM, William Clodius wrote:
> ...
> ...
> > 2. The other cases. Oh my. Although functions are allowed to have side
> > effects as long as you avoid the restrictions mentioned above, you are
> > not necessarily allowed to depend on those side effects.
>
> But for a well-defined case, would the standard
> not give an answer?
Define "well-defined". I know of no such definition that applies. To the
contrary, the standard explicitly says, in f2003 7.1.8.1
"If a statement contains a function reference in a part of an
expression that need not be evaluated, all entities that would
have become defined in the execution of that function reference
become undefined..."
Alas, the condition in that sentence in the standard is the subject of
much controversy. It refers to the preceding para, which says
"It is not necessary for a processor to evaluate all of the operands
of an expression, or to evaluate entirely each operand, if the value
of the expression can be determined otherwise."
That condition is intended to facilitate optimizations. The
interpretations vary widely as to what could validly be considered to be
a way to "otherwise" determine the value. An extreme interpretation is
that there is always some way that count as otherwise. The compiler
could get the value from divine inspiration if it has the appropriate
hardware support (a soul, perhaps "the soul of a new machine" :-)). Or
still pretty ridculous, but back to the realm of things obviously
possible, the compiler could save the machine state, do the same
operations as would be involved in executing the function to determine
the value, and restore the machine state except for remembering the
computed result value. I recall hearing people opine that while the
later approach was admitedly silly, it was technically allowed by the
wording in the standard. I might add that a variant of it now seems a
little bit less silly than the original. Instead of saving and restoring
state, imagine copying the needed data to some parallel process that
computed the function result, but didn't necessarily copy back any
modified private memory. Probably still a little extreme, but not so
completely ludicrous.
It sounds to me as though you have not previously seen these discussions
of function side effects. If so, let me caution you against making
assumptions about how they have to work.
This subthread started in relation to pseudo-random number generators.
That is actually one of the cases where real programs have actually hit
bugs because of this issue. Pseudo-random number generators just happen
to get used in ways that are prone to trigger the bugs. For example, if
you try to approximate a normal distribution by averaging several
uniforms using code like
x = (rand(seed)+rand(seed)+rand(seed))/3.0
don't be shocked if the compiler optimizes that to
x = rand(seed)
(Ok, 3 is a bit few for even a rough approximation, but that's all I
wanted to write out here.)
> It seems clumsy...
Sorry, but I don't find that a very convincing argument. Oh sure, I
agree that it seems clumsy. But I don't buy that as grounds for
interpreting the words of the standard. Perhaps grounds for pushing for
changes in the words of the standard, though good luck with that. I
shouldn't phrase it quite that way because the "good luck" isn't
entirely facetious. I seriously do wish the standard could be clarified
in this area and so I actually do wish good luck. I just burned out on
pushing for such clarification myself a long time ago. As a warning, if
you try to tie down side effects to much, you'll likely run into very
heated opposition from people who want to give optimizers free reign.
And before log, someone else will probably speak up, because I don't
think I can go on for this long on this particular subject without
having someone say I got it all wrong. :-( Or at least some wrong.