By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,688 Members | 1,845 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,688 IT Pros & Developers. It's quick & easy.

volatile expression

P: n/a
Given this code:

extern volatile unsigned char v;

int main(void)
{
v;

return 0;
}

My understanding is that that "v;" is an expression statement which
should be "evaluated" as a void expression for side effects, but that
"evaluation" requires an operator. Does changing the statement to

v + 0;

or

(v);

change this?

I have some compilers which do and some compilers which do not access
"v" with the above code.

--
John W. Temples, III
Nov 14 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a
John Temples <us****@xargs-spam.com> scribbled the following:
Given this code: extern volatile unsigned char v; int main(void)
{
v; return 0;
} My understanding is that that "v;" is an expression statement which
should be "evaluated" as a void expression for side effects, but that
"evaluation" requires an operator. Does changing the statement to v + 0; or (v); change this? I have some compilers which do and some compilers which do not access
"v" with the above code.


"v;" is very much an expression, just like "v + 0;" and "(v);" are. If a
compiler does not evaluate the value of the volatile variable v in the
expression "v;", then it is breaking the standard. The C standard
expressly dictates that any mention of a volatile variable in an
expression must result in evaluation of that variable's value.
Non-volatile variables can be optimised away in such expressions but
volatile variables cannot.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"Stronger, no. More seductive, cunning, crunchier the Dark Side is."
- Mika P. Nieminen
Nov 14 '05 #2

P: n/a
In article <news:6a********************@iswest.net>
John Temples <us****@xargs-spam.com> wrote:
[trimmed]
extern volatile unsigned char v;
v;
My understanding is that that "v;" is an expression statement which
should be "evaluated" as a void expression for side effects ...
I have some compilers which do and some compilers which do not access
"v" with the above code.


Here is a quote from a C99 draft (wording essentially unchanged from
the original 1989 ANSI C standard):

[#6] An object that has volatile-qualified type may be
modified in ways unknown to the implementation or have other
unknown side effects. Therefore any expression referring to
such an object shall be evaluated strictly according to the
rules of the abstract machine, as described in 5.1.2.3.
Furthermore, at every sequence point the value last stored
in the object shall agree with that prescribed by the
abstract machine, except as modified by the unknown factors
mentioned previously.99 What constitutes an access to an
object that has volatile-qualified type is implementation-
defined.

The last sentence is the key here: the implementation's documentation
must state what make something an "access" to a volatile-qualified-type
object like "v".

So, open up the documentation that came with your compiler, see
whether it says "v;" constitutes an "access", and you will find
out whether the compiler should have generated one.

(In practice, given the option, I personally would reject -- or at
least seriously downgrade -- any compiler that does not attempt to
"load v" here, regardless of the contents of the implementation
document. Of course, one must often trade off obnoxious compiler
behavior against required compiler features. But if the document
says "v;" is an access, and the compiler generates no code, you have
obvious grounds for a bug report, at least.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #3

P: n/a
In article <ch**********@oravannahka.helsinki.fi>,
Joona I Palaste <pa*****@cc.helsinki.fi> wrote:
John Temples <us****@xargs-spam.com> scribbled the following:
Given this code:
extern volatile unsigned char v;

int main(void)
{
v;

return 0;
}

[snippage]
"v;" is very much an expression, just like "v + 0;" and "(v);" are. If a
compiler does not evaluate the value of the volatile variable v in the
expression "v;", then it is breaking the standard.
Isn't that a little bit strong?
The C standard
expressly dictates that any mention of a volatile variable in an
expression must result in evaluation of that variable's value.


I thought it was any *access to* a volatile object, where exactly what
constitutes an access is implementation-defined.
So if the implementor, for some reason, chooses to not define this
as an access to v, then it's acceptable to not generate code for it.
(Whether such a compiler can be trusted to get volatile accesses in more
complex expressions "right" is of course a different matter.)
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca
Practical Solution #1: Kill the programmer in question. This is
also the most satisfying solution, because it ensures that the
problem will not recur. --Ben Pfaff in comp.lang.c
Nov 14 '05 #4

P: n/a
John Temples <us****@xargs-spam.com> writes:
Given this code:

extern volatile unsigned char v;

int main(void)
{
v;

return 0;
}

My understanding is that that "v;" is an expression statement which
should be "evaluated" as a void expression for side effects,
Yes.
but that
"evaluation" requires an operator.

[...]

Why do you think that evaluation requires an operator?

There is a flaw in the standard's definiion of "expression".
C99 6.5p1 says:

An _expression_ is a sequence of operators and operands that
specifies computation of a value, or that designates an object or
a function, or that generates side effects, or that performs a
combination thereof.

which, taken literally, implies that v is not an expression, since it
contains no operators or operands. But it's clearly the intent that v
is an expression (see the grammar), and that it can be evaluated.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #5

P: n/a
On Tue, 7 Sep 2004 20:46:06 +0000 (UTC), dj******@csclub.uwaterloo.ca
(Dave Vandervies) wrote in comp.lang.c:
In article <ch**********@oravannahka.helsinki.fi>,
Joona I Palaste <pa*****@cc.helsinki.fi> wrote:
John Temples <us****@xargs-spam.com> scribbled the following:
Given this code:

extern volatile unsigned char v;

int main(void)
{
v;

return 0;
}

[snippage]
"v;" is very much an expression, just like "v + 0;" and "(v);" are. If a
compiler does not evaluate the value of the volatile variable v in the
expression "v;", then it is breaking the standard.


Isn't that a little bit strong?
The C standard
expressly dictates that any mention of a volatile variable in an
expression must result in evaluation of that variable's value.


I thought it was any *access to* a volatile object, where exactly what
constitutes an access is implementation-defined.
So if the implementor, for some reason, chooses to not define this
as an access to v, then it's acceptable to not generate code for it.
(Whether such a compiler can be trusted to get volatile accesses in more
complex expressions "right" is of course a different matter.)
dave


I was going to jump on you, but it is just as well point you to Chris
Torek's detailed answer to the OP.

As for the bit about what constitutes an access to a volatile object
is implementation defined, I agree that the standard has muddied the
water for 15 years and the wording should be expanded to explain the
(claimed) intent.

Consider:

volatile unsigned char vuc [8];
/* ... */
int x = vuc [3];

On your average, everyday, Pentium, 64 bits (8 octets) are going to be
read from memory. Depending on the alignment of 'vuc', all eight of
those volatile unsigned chars may actually be read, even though all
but one of them will be ignored.

Supposedly the wording about what constitutes access is intended to
cover situations like this, meaning that a read of vuc [3] might well
cause a read of other elements. But it should clearly do a better job
of saying so.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #6

P: n/a
Keith Thompson wrote:
John Temples <us****@xargs-spam.com> writes:
but that
"evaluation" requires an operator.


[...]

Why do you think that evaluation requires an operator?


The C90 standard (to which the compilers I am testing claim to comply)
defines the term "evaluation" in 6.1.5 as "An operator specifies an
operation to be performed (an _evaluation_) [...]" C99 doesn't appear
to have this explicit definition of "evaluation."

--
John W. Temples, III
Nov 14 '05 #7

P: n/a
John Temples <us****@xargs-spam.com> writes:
Keith Thompson wrote:
John Temples <us****@xargs-spam.com> writes:
but that
"evaluation" requires an operator.

[...]
Why do you think that evaluation requires an operator?


The C90 standard (to which the compilers I am testing claim to comply)
defines the term "evaluation" in 6.1.5 as "An operator specifies an
operation to be performed (an _evaluation_) [...]" C99 doesn't appear
to have this explicit definition of "evaluation."


I've found that the standard's definitions, at least the ones defining
a term in italic type, are often incomplete. (See C99's definition of
"lvalue" for an example -- but that particular case has already been
argued to death in comp.std.c.) The more explicit definitions in
section 3 tend to be better. (In my opinion, disclaimer disclaimer,
blah blah.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #8

P: n/a
In <4v********************************@4ax.com> Jack Klein <ja*******@spamcop.net> writes:
As for the bit about what constitutes an access to a volatile object
is implementation defined, I agree that the standard has muddied the
water for 15 years and the wording should be expanded to explain the
(claimed) intent.


I strongly suspect that the standard is worded in such a way as to make
"volatile" next to useless (except in the context of signals and longjmp)
for purely political reasons that are far from volatile and so is the
wording in question.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Currently looking for a job in the European Union
Nov 14 '05 #9

P: n/a
In <6a********************@iswest.net> John Temples <us****@xargs-spam.com> writes:
Given this code:

extern volatile unsigned char v;

int main(void)
{
v;

return 0;
}

My understanding is that that "v;" is an expression statement which
should be "evaluated" as a void expression for side effects, but that
"evaluation" requires an operator. Does changing the statement to

v + 0;

or

(v);

change this?
No, the expressions are equivalent.
I have some compilers which do and some compilers which do not access
"v" with the above code.


So, avoid it. A much safer approach is:

extern volatile unsigned char v;
void nop(unsigned char);

int main()
{
nop(v);
return 0;
}

For best results, define nop() in a different file. In theory, a super
smart implementation could still optimise away the nop() call, but real
implementations are not that smart...

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Currently looking for a job in the European Union
Nov 14 '05 #10

P: n/a
Keith Thompson <ks***@mib.org> writes:
John Temples <us****@xargs-spam.com> writes:

My understanding is that that "v;" is an expression statement which
should be "evaluated" as a void expression for side effects,


[...]

Why do you think that evaluation requires an operator?

There is a flaw in the standard's definiion of "expression".
C99 6.5p1 says:

An _expression_ is a sequence of operators and operands that
specifies computation of a value, or that designates an object or
a function, or that generates side effects, or that performs a
combination thereof.

which, taken literally, implies that v is not an expression, since it
contains no operators or operands.


It seems true that "v" by itself is an operand, and specifies
computation of a value. Consider

return v;

It also seems true that "v" is a sequence of { operators, operands },
if you get my meaning. So although the wording is a little funny,
the language here could be read to say that "v;" is an expression
and so must be evaluated.
Nov 14 '05 #11

P: n/a
Tim Rentsch <tx*@alumnus.caltech.edu> writes:
Keith Thompson <ks***@mib.org> writes:
John Temples <us****@xargs-spam.com> writes:
>
> My understanding is that that "v;" is an expression statement which
> should be "evaluated" as a void expression for side effects,
[...]

Why do you think that evaluation requires an operator?

There is a flaw in the standard's definiion of "expression".
C99 6.5p1 says:

An _expression_ is a sequence of operators and operands that
specifies computation of a value, or that designates an object or
a function, or that generates side effects, or that performs a
combination thereof.

which, taken literally, implies that v is not an expression, since it
contains no operators or operands.


It seems true that "v" by itself is an operand, and specifies
computation of a value. Consider

return v;


An operand is defined, in C99 6.4.6p2, as "an entity on which an
operator acts". return is not an operator.
It also seems true that "v" is a sequence of { operators, operands },
if you get my meaning. So although the wording is a little funny,
the language here could be read to say that "v;" is an expression
and so must be evaluated.


If there's no operator, there's no operand.

To be clear, there is no doubt in my mind that "v" by itself is
(intended to be) an expression. My quibble is with the wording of the
standard's definition; the intent is clear.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #12

P: n/a
Keith Thompson <ks***@mib.org> writes:
Tim Rentsch <tx*@alumnus.caltech.edu> writes:
Keith Thompson <ks***@mib.org> writes:
John Temples <us****@xargs-spam.com> writes:
>
> My understanding is that that "v;" is an expression statement which
> should be "evaluated" as a void expression for side effects,

[...]

Why do you think that evaluation requires an operator?

There is a flaw in the standard's definiion of "expression".
C99 6.5p1 says:

An _expression_ is a sequence of operators and operands that
specifies computation of a value, or that designates an object or
a function, or that generates side effects, or that performs a
combination thereof.

which, taken literally, implies that v is not an expression, since it
contains no operators or operands.


It seems true that "v" by itself is an operand, and specifies
computation of a value. Consider

return v;


An operand is defined, in C99 6.4.6p2, as "an entity on which an
operator acts". return is not an operator.


If I'm not mistaken, 6.4.6p2 also says "other forms of operators also
exist in some contexts".

Is "v" by itself an expression? 6.5.1p2, "An identifier is a primary
expression, provided it has been declared as designating an object
[...]".

Does the appearance of "v" in a return statement make it an
expression? 6.8p2, "A full expression is an expression that is not
part of another expression or declarator. Each of the following is a
full expression: an initializer; the expression in an expression
statement; the controlling expression of a selection statement ('if'
or 'switch'); the controlling expression of a 'while' or 'do'
statement; each of the (optional) expressions of a 'for' statement;
the (optional) expression in a 'return' statement.

It also seems true that "v" is a sequence of { operators, operands },
if you get my meaning. So although the wording is a little funny,
the language here could be read to say that "v;" is an expression
and so must be evaluated.


If there's no operator, there's no operand.


If the notion of operator in 6.4.6p2 were defined exhaustively then it
might be reasonable to conclude that there's no operator. But it's
specifically not exhaustive.

What follows 'return' _is_ an expression; hence the "v" must be an
operand (unless you want to argue that "v" is an operator :); hence
there must be an operator. We can only conclude that the operator
here is one of the "other forms of operators [that] also exist in some
contexts".

Don't get me wrong, I think the wording is poor. But the language
does allow us to conclude that (in an appropriate context) an
identifier by itself is indeed an expression.

Nov 14 '05 #13

P: n/a
Tim Rentsch <tx*@alumnus.caltech.edu> writes:
Keith Thompson <ks***@mib.org> writes:
Tim Rentsch <tx*@alumnus.caltech.edu> writes:
> Keith Thompson <ks***@mib.org> writes:
>> John Temples <us****@xargs-spam.com> writes:
>> >
>> > My understanding is that that "v;" is an expression statement which
>> > should be "evaluated" as a void expression for side effects,
>>
>> [...]
>>
>> Why do you think that evaluation requires an operator?
>>
>> There is a flaw in the standard's definiion of "expression".
>> C99 6.5p1 says:
>>
>> An _expression_ is a sequence of operators and operands that
>> specifies computation of a value, or that designates an object or
>> a function, or that generates side effects, or that performs a
>> combination thereof.
>>
>> which, taken literally, implies that v is not an expression, since it
>> contains no operators or operands.
>
> It seems true that "v" by itself is an operand, and specifies
> computation of a value. Consider
>
> return v;
An operand is defined, in C99 6.4.6p2, as "an entity on which an
operator acts". return is not an operator.


If I'm not mistaken, 6.4.6p2 also says "other forms of operators also
exist in some contexts".


Yes, it does. Section 6.4.6 is about "punctuators". The "other
forms" clause refers to operators that don't have the form of a single
punctuator, such as the sizeof, cast, and array indexing operators.
You're right, the definition of "operator" in C99 6.4.6p2 is
explicitly not exhaustive. That just means that there are other
things that the standard explicitly refers to as operators.
Is "v" by itself an expression? 6.5.1p2, "An identifier is a primary
expression, provided it has been declared as designating an object
[...]".

Does the appearance of "v" in a return statement make it an
expression? 6.8p2, "A full expression is an expression that is not
part of another expression or declarator. Each of the following is a
full expression: an initializer; the expression in an expression
statement; the controlling expression of a selection statement ('if'
or 'switch'); the controlling expression of a 'while' or 'do'
statement; each of the (optional) expressions of a 'for' statement;
the (optional) expression in a 'return' statement.
In "return v;", yes, v is an expression (or else the statement is
illegal). It's obviously the intent of the standard that v, by
itself, is a legal expression (assuming there's an appropriate
declaration in scope). The only problem is that the standard's
definition of "expression" doesn't correctly express this fact.

(Incidentally, the presence of "v" in "return v;" isn't what implies
that "v" is an expression, any more than the presence of "int" in
"return int;" implies that "int" is an expression. The implication
goes the other way; the fact that "v" is a valid expression implies
that "return v;" is a valid return statement.)
> It also seems true that "v" is a sequence of { operators, operands },
> if you get my meaning. So although the wording is a little funny,
> the language here could be read to say that "v;" is an expression
> and so must be evaluated.


If there's no operator, there's no operand.


If the notion of operator in 6.4.6p2 were defined exhaustively then it
might be reasonable to conclude that there's no operator. But it's
specifically not exhaustive.


If there were any indication in the standard that there's an operator
in either
v;
or
return v;
it would be reasonable to conclude that there is an operator. There
is no such indication.
What follows 'return' _is_ an expression; hence the "v" must be an
operand (unless you want to argue that "v" is an operator :); hence
there must be an operator. We can only conclude that the operator
here is one of the "other forms of operators [that] also exist in some
contexts".

Don't get me wrong, I think the wording is poor. But the language
does allow us to conclude that (in an appropriate context) an
identifier by itself is indeed an expression.


Yes, the wording is poor, but I think your suggested fix requires a
strained interpretation.

C99 6.5p1 says:

An _expression_ is a sequence of operators and operands that
specifies computation of a value, or that designates an object or
a function, or that generates side effects, or that performs a
combination thereof.

Since _expression_ is in italic type, this is the standard's
definition of the term. There is no statement that it's not
exhaustive (and if it's not exhaustive, it's not a definition). It
implies that anything that doesn't consist of "operators and operands"
is not an expression. Of course an identifier that refers to an
object is an expression, but there's no visible operator (and no
justification for assuming that there's an invisible operator), and
therefore no operand (see the definition of "operand").

I suggest that this problem should be fixed by improving the wording
of the definition of "expression", to acknowledge explicitly that not
all expressions consist of operators and operands. You suggest
leaving the definition as it is, and inventing invisible implicit
operators (which the standard does not mention anywhere) to force
certain cases to fit the definition. Sorry, but I like my idea
better.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #14

P: n/a
Keith Thompson <ks***@mib.org> wrote:

In "return v;", yes, v is an expression (or else the statement is
illegal). It's obviously the intent of the standard that v, by
itself, is a legal expression (assuming there's an appropriate
declaration in scope). The only problem is that the standard's
definition of "expression" doesn't correctly express this fact.


Most definitions are incomplete in one way or another -- check any
dictionary for numerous examples. That fact that the English definition
of "expression" in the standard misses the degerate case that's included
in the formal (BNF) definition doesn't bother me at all; I don't expect
that any reader will be seriously confused or think that the informal
definition somehow overrides the formal one. Trying to enhance the
current definition to be more complete strikes me as errant pedantry.

-Larry Jones

The living dead don't NEED to solve word problems. -- Calvin
Nov 14 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.