strange grammar about volatile and operator overload

G

George2

Hello everyone,


The following code,

Code:
operator const Outer::Inner * volatile & ();

1.

I think it means an operator &, which returns const Inner* type and
takes no arguments, right?

2.

Adding volatile to return value means?

(I previously only used volatile to qualify variable)


thanks in advance,
George
 
A

Alf P. Steinbach

* George2:
> The following code,

Code:
operator const Outer::Inner * volatile & ();

1.

I think it means an operator &, which returns const Inner* type and
takes no arguments, right?

no, it's like

operator int();


2.

Adding volatile to return value means?

Depends what it's used for. The basic C level meaning of 'volatile' has
turned out to be mostly irrelevant in practice, doesn't do the job. But
in C++ 'volatile' can play a role in the type system, akin to 'const',
and perhaps that's what it's used for here, to make a type distinction.


Cheers & hth.,

- Alf
 
H

Hans Mull

George2 said:
Hello everyone,


The following code,

Code:
operator const Outer::Inner * volatile & ();

1.

I think it means an operator &, which returns const Inner* type and
takes no arguments, right?

2.

Adding volatile to return value means?

(I previously only used volatile to qualify variable)


thanks in advance,
George
volaitle disables optimization

Kind regards
 
J

Jack Klein

George2 said:
Hello everyone,


The following code,

Code:
operator const Outer::Inner * volatile & ();

1.

I think it means an operator &, which returns const Inner* type and
takes no arguments, right?

2.

Adding volatile to return value means?

(I previously only used volatile to qualify variable)


thanks in advance,
George
volaitle disables optimization

What a silly, incomplete, and absolutely wrong statement!

Consider this code:

extern volatile unsigned int vui; // defined and initialized elsewhere

unsigned int silly_func()
{
return vui * 2;
}

Are you really claiming that the compiler is forbidden from making the
strength reduction optimization of replacing the multiply with a left
shift by 1?

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
J

James Kanze

George2 said:
The following code,
Code:
operator const Outer::Inner * volatile & ();
1.
I think it means an operator &, which returns const Inner*
type and takes no arguments, right?

That would be:
const Outer::Inner * volatile operator & ();

The above is an implicit conversion operator, converting the
class in which it is defined to a Outer::Inter const* volatile&.

A top level volatile on a return value is ignored unless the
type is a class type. Here 1) the type isn't a class type, but
a reference, and 2) the volatile isn't top level, i.e. it isn't
on the return type. What the volatile means here is that you
limit enormously what the user can do with the pointer referred
to. (As Alf pointed out, this is probably a case of exploiting
the type system---what's important here isn't the semantics of
volatile, but the fact that T* volatile isn't the same type as
T* volatile.)
What a silly, incomplete, and absolutely wrong statement!

It's incomplete, but that's all. Formally, except for a few
special cases (e.g. with longjmp/setjmp), the semantics of
volatile are implementation defined. Practically, however, most
implementations define them as inhibiting some optimizations.
Consider this code:
extern volatile unsigned int vui; // defined and initialized elsewhere
unsigned int silly_func()
{
return vui * 2;
}
Are you really claiming that the compiler is forbidden from
making the strength reduction optimization of replacing the
multiply with a left shift by 1?

No, but if the compiler inlines this function, and happens to
find that it has vui in a register, as a result of a previous
calculation, it will still reread it. (Or more correctly, it
will still generate a machine instruction to load it from
memory. On most modern hardware, this does not necessarily mean
that it will actually reread it from global memory. In sum, the
implementation defined semantics of volatile are, in most cases,
totally useless for anything.)
 
G

Gerhard Fiedler

what's important here isn't the semantics of volatile, but the fact that
T* volatile isn't the same type as T* volatile.)

Is this a typo? If not, could you please explain?
In sum, the implementation defined semantics of volatile are, in most
cases, totally useless for anything.

Does this mean that it is not necessary to declare variables that are
accessed (read and write) by different threads as volatile? (In addition to
the necessary locking, of course.)

Gerhard
 
D

Diego Martins

Is this a typo? If not, could you please explain?


Does this mean that it is not necessary to declare variables that are
accessed (read and write) by different threads as volatile? (In addition to
the necessary locking, of course.)

Gerhard

I will extend the Gerhard's question to: "and what about pointer to
memory mapped addresses?"

Diego
 
J

James Kanze

On 2008-01-30 08:50:26, James Kanze wrote:
Is this a typo?

I think so:). What I probably meant to say was that T*& isn't
the same as T* volatile&. (Note that T* volatile and T* are the
same types, at least when they're return values.)

[...]
Does this mean that it is not necessary to declare variables
that are accessed (read and write) by different threads as
volatile? (In addition to the necessary locking, of course.)

It depends on what the threading specifications (and the
compiler definition of volatile) say. Under Posix, if you
haven't locked, volatile isn't sufficient, and if you have, it
isn't necessary. Current Windows works about the same, I think,
although I find it very hard to find any real published
specifications.
 
J

James Kanze

On Jan 30, 10:00 am, Gerhard Fiedler <[email protected]> wrote:

[...]
I will extend the Gerhard's question to: "and what about pointer to
memory mapped addresses?"

I presume that you mean memory mapped I/O.

Implementation defined:). At least on a Sparc, there is no way
to access memory mapped I/O without using at least some
assembler, at least with Sun CC or g++. Intel has special I/O
instructions, and doesn't normally use memory mapped I/O---if it
does (and why not), then it depends on the backing hardware, but
I can't imagine it working unless the instructions accessing it
were prefixed with a lock, something none of the Intel compilers
I've seen do, even with volatile.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,818
Latest member
SapanaCarpetStudio

Latest Threads

Top