This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Volatile MEMs in statement expressions and functions inlined as trees


On 17-Dec-2001, Linus Torvalds <torvalds@transmeta.com> wrote:
> On Tue, 18 Dec 2001, Fergus Henderson wrote:
> > On 13-Dec-2001, Linus Torvalds <torvalds@transmeta.com> wrote:
> > >
> > > For an expression like
> > >
> > > 	extern volatile in p;
> > > 	p;
> > >
> > > you would expect to see the assembly code to contain a dereference of "p",
> > > would you not?
> >
> > No.  I wouldn't know what to expect.
> 
> Well, how about reading the C++ standard on what "volatile" means?

Well, my understanding is that the standard is not very helpful here,
because the semantics of volatile are defined with respect to
"access" to volatile objects, but "access" is not defined.
In C "access" is defined to mean reading or modifying an object,
but the definition of "what constitutes access to a volatile object"
is then left explicitly implementation-defined.
In C++ "access" is implicitly undefined by virtue of not being
explicitly defined anywhere.

My understanding from prior discussions about this is that the reason
it was left deliberately implementation-defined in C is because there
are some genuinely tricky cases where it was thought to be better to
leave the exact definition up to the implementation.

For example, consider the following code:

	struct s {
		int x: 4;
		volatile int y: 4;
	};

	void foo(s *p) {
		p->x++;
	}

Should this constitute an access to p->y?

> As far as I can tell, there are only two places that actually talk about
> the _meaning_ of volatile, as opposed to just mentioning it as a
> cv-qualifier. The places I've found (please add your own list here) are:
[...]
> Do you find any other place that talks about the _semantics_ of volatile?

There are a few other parts of 1.9 (paragraphs 6 and 11) and
7.1.5.1 (paragraph 7) which talk about the semantics of volatile,
in addition to the parts that you quoted, but I don't think they
are particularly relevant to this discussion.

> Now, in C, the meaning of
> 
> 	volatile int p;
> 	p;
> 
> is pretty clear: we _will_ load the value from "p", because the value of
> the expression is the value of "p" and C does not have any of the lvalue
> vs rvalue confusion that C++ has.

I disagree that this is clear.  I believe that an implementation would
be permitted to define "what constitutes access to a volatile object"
so that using a volatile object as an expression-statement would not
constitute access to it.

> It sounds like lcc and Sun cc have gotten confused about C semantics, and
> I suspect that the _reason_ for the confusion is that they're trying to
> compile C++ too, a language that is inherently confused about this.

lcc is a C compiler only, not a C++ compiler, so your hypothesis is
definitely wrong in the case of lcc.

> So, put the three together:
> 
>  - C semantics are clear: the expression "p" is _identical_ in both of
>    the statements "p;" and "i = p;". It should thus behave the same way.
> 
>  - C++ semantics are less clear, but gcc documentation implies that the
>    access is _allowed_ by the standard, and the standard clearly does say
>    that C++ semantics are _indended_ to be identical to C semantics.
> 
> So what do you say?

I think that in neither C nor C++ are the semantics clear.

For C, I think that if you define "what constitutes access to a volatile
object" in the most obvious way, then the most natural interpretation
is that "p;" would load "p",  However, I don't think the C standard
mandates this.

For C++, I think the most natural interpretation is that "access" to
an lvalue occurs during the lvalue-to-rvalue conversion, and there is
no lvalue-to-rvalue conversion for "p;", so "p;" should not load "p".
However, because "access" is not explicitly defined, I don't think the
standard is sufficiently clear to definitively answer the question.

The semantics of "volatile" are intended to be identical to C semantics,
but difference in the most natural interpretation for the behaviour of "p;"
is due to differences in when the lvalue-to-rvalue conversion is applied
(6.3.2.1 [#2] in the C standard, 4.1 [conv.lval] in the C++ standard),
rather than to differences in the semantics of "volatile".

However, it is certainly undesirable for C++ to differ from C in this
respect, and it quite likely that this was not intended.  So I think
a defect report is warranted.

As for what GNU C and GNU C++ should do, I don't have a strong preference,
so long as they issue a warning.  Probably it would be best to maintain
backward compatibility with whatever they used to do.

-- 
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]