Re: volatile Info



On Aug 6, 12:22 pm, Keith Thompson <ks...@xxxxxxx> wrote:

The function in question was roughly (changing the name of the
parameter for clarity):

int square(volatile int x) {
    return x * x;

}

Given that x is declared volatile, it's theoretically possible
that the two references to x in the return statement could yield
different values because some outside entity changed x's value
during the evaluation of the expression.  Also, accessing x is by
definition a side effect (see 5.1.2.3p2); this side effect could
affect the visible behavior of the program.  For example, accessing
x might implicitly cause it to be incremented.

When I say that something is "theoretically possible", I merely mean
that if it did happen, it would not violate the requirements of the
Standard, not that it's at all likely to happen under some actual
non-DS9K implementation.

Consider the following program:

#include <stdlib.h>

int square(volatile int x) {
    return x * x;

}

int main(void) {
    return square(10) == 100 ? EXIT_SUCCESS : EXIT_FAILURE;

}

If this program returns an unsuccessful termination status to
the environment, that doesn't imply that the implementation is
non-conforming.

On the other hand, if a modified version of this program with the
"volatile" keyword deleted returns an unsuccessful termination status
to the environment, then the implementation *is* non-conforming.

"volatile" gives the implementation permission to cause a program
to behave in certain ways that it would not otherwise be permitted
to behave.  An implementation is not obligated to take advantage
of this permission.

In this particular case, I'd be astonished if the "volatile"
keyword affected the visible behavior of the program (though it
might well affect the generated code).  The authors of the standard,
quite rightly IMHO, did not restrict the use of "volatile" to cases
where it makes sense.

First off, I totally agree that this is all rather academic unless
you actually own a DS9K.

And I can't quite put my finger on what I'm trying to get at here,
so bear with me =)

Let's say that there _is_ some mechanism by which an object's value
may change, independently of what the abstract machine would otherwise
dictate. Modifying your example above:

<code>
/* assume that this is an implementation-defined memory-mapped
register that _ought_ to be treated as volatile. */
int *reg = 0x4000

#include <stdlib.h>

/* The parameter here _ought_ be declared as volatile. */
int square(int *x) {
return *x * *x;
}

int main(void) {
*reg = 10;
return square(reg) == 100 ? EXIT_SUCCESS : EXIT_FAILURE;
}
</code>

(I think I got that right).

In parallel to your explanation with your original example, I think
you're suggesting that the implementation is non-conforming if
this program returns EXIT_FAILURE.

Does this code exhibit undefined behaviour? Unless I made a mistake
or missed something, I don't think so (ignoring overflow,
as usual).

So it seems peculiar to me that the programmer can render the
implementation non-conforming by omitting the volatile in the
declaration of square().
.