Topic: Volatile objects and expressions (was: &array[-3] allowed?)


Author: gurnec@my-dejanews.com
Date: 1998/10/11
Raw View
In article <6vifpd$l9c$1@nnrp1.dejanews.com>,
  markw65@my-dejanews.com wrote:
>
> In article <6vg6qb$s28$1@nnrp1.dejanews.com>,
>   AllanW@my-dejanews.com wrote:

<clip>

> > I've just spent two hours trying to write a clear and yet extremely
> > detailed account of why my interpretation was the only correct one.
> >
> > I failed! I am now absolutely convinced that if operator= returns
> > an lvalue, then
> >     nv = (v = 0);
> > must write into v, and then re-read the value back out again -- just
> > as James spelled out above. Perhaps what I wrote above would work in
> > C, I don't know any more.
>
> In C++ the result of the assignment _is_ an lvalue, but its type is the
> *unqualified* type of the lhs (at least for builtin types, and for class
> types it all depends on the assignment operator). So presumably although the
> abstract machine is required to re-read the value from v, a real
> implementation is allowed to optimize the read away, and use the stored
> value, ie zero in this case.

I think you misread the standard.  From 5.17:

1. ... the type of an assignment expression is that of its left operand....

3. If the left operand is not of class type, the expression is implicitly
converted (clause 4) to the cv-unqualified type of the left operand.

Here, "the expression" refers to the right operand, not the entire assignment
expression.  It _is_ a bit confusing, but I'm pretty sure that this is the
intended meaning (not positive).  So the cv-qualifiers of the left operand are
not dropped.

So we're back to requiring a read if that lvalue result is used.

<clip>

> > May I please ask someone on the C++ standardization committee to explain
> > WHY the result of operator= is an lvalue? Are we trying to support code
> > such as
> >     ((v = 3) = 5) = 7;
> > which now seems to be legal, and even works on my compiler? What's the
> > point of this?
> >
> > > Going back to the original:
> > >
> > > v;
> > >
> > > Is that an lvalue or rvalue expression?  In which language?
>
> > I am still convinced that this is an lvalue expression in either
> > language (C or C++). (Remember that lvalues can be converted into
> > rvalues, so really the answer is "both".) But the question was,
> > does this require an access to v's value? If so, is it a read
> > access or a writeaccess -- and if it's a write access, what is
> > written?
>
> > I still feel that this should be a no-op, even if v is volatile,
> > but I'm no longer as certain as I once was...
>
> > > Any deconfusion available?
>
> > Please...
>
> An lvalue (except as the operand of one of a small set of operators) is
> converted to the value stored in it. ie, in the abstract machine, it is read.
> Since v is volatile, its value must be read.

But as an expression-statement, e.g. as in:
 v;
the lvalue-to-rvalue standard conversion is suppressed (IS 6.2/1).  I can't
seem to find any way to interpret the standard such that an access of any type
to v is required (or for that matter, even allowed).  I might have, of course,
missed something on one of the 700+ pages :-)

-Chris Gurnee

--

mangled email: gurnec_at_mediaone_dot_net

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: markw65@my-dejanews.com
Date: 1998/10/12
Raw View
In article <6vkahp$7kf$1@nnrp1.dejanews.com>,
  gurnec@my-dejanews.com wrote:
> In article <6vifpd$l9c$1@nnrp1.dejanews.com>,
>   markw65@my-dejanews.com wrote:
[snip]
> >
> > In C++ the result of the assignment _is_ an lvalue, but its type is the
> > *unqualified* type of the lhs (at least for builtin types, and for class
> > types it all depends on the assignment operator). So presumably although the
> > abstract machine is required to re-read the value from v, a real
> > implementation is allowed to optimize the read away, and use the stored
> > value, ie zero in this case.

> I think you misread the standard.  From 5.17:

> 1. ... the type of an assignment expression is that of its left operand....

> 3. If the left operand is not of class type, the expression is implicitly
> converted (clause 4) to the cv-unqualified type of the left operand.

> Here, "the expression" refers to the right operand, not the entire assignment
> expression.  It _is_ a bit confusing, but I'm pretty sure that this is the
> intended meaning (not positive).  So the cv-qualifiers of the left operand are
> not dropped.

I dont think so, but you are obviously right about it being confusing :-)
"The expression" cannot refer to anything other than the whole expression.


> So we're back to requiring a read if that lvalue result is used.

No.


> <clip>
> >
> > An lvalue (except as the operand of one of a small set of operators) is
> > converted to the value stored in it. ie, in the abstract machine, it is
read.
> > Since v is volatile, its value must be read.

> But as an expression-statement, e.g. as in:
>  v;
> the lvalue-to-rvalue standard conversion is suppressed (IS 6.2/1).  I can't
> seem to find any way to interpret the standard such that an access of any type
> to v is required (or for that matter, even allowed).  I might have, of course,
> missed something on one of the 700+ pages :-)

Yes, there is a difference here between the C and C++ standards. What I wrote
applies to C (in the expression-statement "v;", v is converted to an r-value).
But, as you point out, the rule in C++ is different, and v can remain an
l-value.

Mark Williams

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: gurnec@my-dejanews.com
Date: 1998/10/12
Raw View
In article <6vrbj7$ui9$1@nnrp1.dejanews.com>,
  markw65@my-dejanews.com wrote:
>
> In article <6vkahp$7kf$1@nnrp1.dejanews.com>,
>   gurnec@my-dejanews.com wrote:
>
> > 1. ... the type of an assignment expression is that of its left operand....
>
> > 3. If the left operand is not of class type, the expression is implicitly
> > converted (clause 4) to the cv-unqualified type of the left operand.
>
> > Here, "the expression" refers to the right operand, not the entire
assignment
> > expression.  It _is_ a bit confusing, but I'm pretty sure that this is the
> > intended meaning (not positive).  So the cv-qualifiers of the left operand
are
> > not dropped.
>
> I dont think so, but you are obviously right about it being confusing :-)
> "The expression" cannot refer to anything other than the whole expression.

I stand by my original interpretation; let me attempt to justify it.  First, I
find it difficult to believe that the intent of the standard was to allow
something like:

void foo(int& i) {i = 1;}

void bar() {
  volatile int vi;
  foo(i);      // illegal
  foo(i = 0);  // legal??
}

Here, the line marked "legal??" is syntactically valid according to your
interpretation, but it produces undefined behavior (modifying a volatile
object through a non-volatile lvalue).  C++'s strong type system was designed
specifically to prevent this type of problem.  Of course, just because I find
that interpretation difficult to believe doesn't mean its wrong (too bad :-).
There are plenty of other examples of that produce undefined behavior, but
this one by contrast seems easily preventable by the existing type system.

This is why I'm trying so hard to interpret the standard so as not to allow
the above.  Let's see how many points I can get for the interpretation that
says "the expression" means "the right operand."

1. The quoted paragraphs (1 and 3) above would be contradictory if "the
expression" meant the entire expression.

2. Paragraph 3 states that "the expression is implicitly converted (clause 4)
to the cv-unqualified type of the left operand."  The only implicit
conversion (correct me if I'm wrong) that can drop cv-qualifiers is an
lvalue-to-rvalue conversion.  If "the expression" refers to the right
operand, this paragraph makes sense.  Otherwise, it means the the result of
the assignment is an rvalue for non-class types, which is clearly not the
case.

3. Paragraph 2, quoted below, is the only place where simple assignment is
defined.

  In simple assignment (=), the value of the expression replaces
  that of the object referred to by the left operand.

This makes perfect sense if "the expression" refers to the right operand, but
if it refers to the entire expression, we get:

  ... the value of the entire expression replaces that of the object ...

So then, what is the value of the entire expression?  You and I of course
know that it is the value of the right operand (and also the left after
assignment), but with this interpretation, the value of the entire expression
is never explicitly defined, so what actually replaces the value of the lhs
object is also not explicitly stated.

Of course, if the standard meant "the right operand," the why didn't it just
say so?  It does in the rest of the Expressions clause.  For this I have no
answer.

Incidentally, VC5 and EGCS 1.1 both agree with the "the right operand"
interpretation, neither will compile my "legel??" example without an error or
at least a warning (respectively).  Not that this really means all that
much...

So, not that the beaten horse is dead and buried, would anyone else care to
express an opinion?

--

mangled email: gurnec_at_mediaone_dot_net

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: markw65@my-dejanews.com
Date: 1998/10/14
Raw View
In article <6vtr08$6jm$1@nnrp1.dejanews.com>,
  gurnec@my-dejanews.com wrote:
> In article <6vrbj7$ui9$1@nnrp1.dejanews.com>,
>   markw65@my-dejanews.com wrote:
> >
> > In article <6vkahp$7kf$1@nnrp1.dejanews.com>,
> >   gurnec@my-dejanews.com wrote:
> >
>
> 3. Paragraph 2, quoted below, is the only place where simple assignment is
> defined.
>
>   In simple assignment (=), the value of the expression replaces
>   that of the object referred to by the left operand.
>
> This makes perfect sense if "the expression" refers to the right operand, but
> if it refers to the entire expression, we get:
>
Agreed. You are correct... Since para 2 clearly uses "the expression" to refer
to the rhs, it makes sense that para 3 does also. But it is extremely poor
wording imho.

Mark Williams

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]