From: Lucian Radu Teodorescu on

Salt_Peter wrote:
> > Is the following code valid?
> >
> > int i = 5;
> > void* pv = &i;
> > void& rv = *pv; // Error here on VC 2005
> >
> > If not, why isn't it valid?
>
> Its not valid for the same reasons that the following is invalid:
> void v = 5;
> That is to say: a reference is an object and a valid object.
> The same can't be said of a pointer, or any pointer.

Let's make the following assumption: every type is implicitly derived
from void. Many C++ programmers can accept that.

Then, is it impossible for us to think of void defined in the following
way:

class void
{
void(); // disabled
void(const void&); // disabled
template <typename T> void(T); // disabled
template <typename T> void operator=(T); // disabled
};

As you can see, we can easisly move from the "there can't be an object
of type void" thinking to the "we can't construct an object of type
void" thinking. The second form of thinking would allow us to have
references to void.

"So, what is this good for?" you might ask. You can't access any
methods to void, you can't call any operator. Still you should be able
to take it's address, and transform it to a pointer like this:

pv = &rv;

The only thing to do is impose that we cannot take the reference to a
void function result. Example:

// This shouldn't be allowed
void f() {}

void& result = f();

I think this constraint is less restrictive than the one we have now
that doesn't allows references to void.

>
> Consider:
> int i = 5;
> What exactly is i ?
> Is it not an alias to what would otherwise have been an anonymous
> variable in memory?
> Granted a reference is not the same beast, but it does serve the same
> purpose.

Ideed, i can be considered a reference to an anonymous variable in
memory. But if you disable the creation of void object, there won't be
any void objects in memory. This means that you can have void
references, but this refenreces must point to variables of types more
specific than void. Of course, we consider here that every other type
is derived from void.

Is there something that I'm missing here?


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: James Kanze on
Joshua Lehrer wrote:
> This has been a pet peeve of mine for a while, probably pretty high up
> on my C++ wish list.

> (ignoring cv-qualifications for simplicity)

> If T* can degrade to void*, why can't T& degrade to void&?

Because void is an incomplete type.

> The following is legal, and the basis of how ScopeGuard works:

> const Base & b = make_sub_class(params);

> The unnamed temporary is bound to the const-reference and is guaranteed
> to be alive for the lifetime of 'b'.

It also only works if Base is a complete type.

> I sometimes find it a pain to make my implementations inherit from a
> common base just so that I can bind a const-reference to the temporary,
> as above. Why can't I write:

> const void & v = make_sub_class(params);

> or

> const void & v = std::pair<Lock,Lock>(mx1,mx2);

> In my mind, it makes sense. All types should be considered to inherit
> (virtually) from void.

What you're looking for isn't void, it's Object. In Java.

Personally, I've never missed it in C++.

--
James Kanze (GABI Software) email:james.kanze(a)gmail.com
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: James Kanze on
Greg Herlihy wrote:
> Lucian Radu Teodorescu wrote:
> > { 8.3.2/1 prohibits declarations of references to void. -mod }

> > Is the following code valid?

> > int i = 5;
> > void* pv = &i;
> > void& rv = *pv; // Error here on VC 2005

> > If not, why isn't it valid?

> For the same reason it is not legal to declare a variable with a void
> type or to dereference a void pointer - "void" in C and C++ denotes
> either that the type is not known (as in the case of a void pointer) or
> there is no type at all (as in the case of a function returning void).

Just a nit, but formally, the situation is a bit more
complicated. Like static, the keyword void is overloaded in
C++. As a type, it's an incomplete type which cannot be
completed. Since it cannot be completed, no objects of the type
can exist, and since a reference must be initialized to
designate an actual object, it makes no sense to allow
references to void. (That's formally, of course. Colloquially,
your statement that it's an unknown type is probably closer to
the way it is used.) As the return value of a function, it's
not really a type; it just says that the function doesn't return
anything. And as the single parameter type of a function, it
says that the function takes no arguments, despite the fact that
one has been declared. (Of course, in C++, we don't use this,
but C programmers do.)

--
James Kanze (GABI Software) email:james.kanze(a)gmail.com
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: James Kanze on
Lucian Radu Teodorescu wrote:
> Salt_Peter wrote:
> > > Is the following code valid?

> > > int i = 5;
> > > void* pv = &i;
> > > void& rv = *pv; // Error here on VC 2005

> > > If not, why isn't it valid?

> > Its not valid for the same reasons that the following is invalid:
> > void v = 5;
> > That is to say: a reference is an object and a valid object.
> > The same can't be said of a pointer, or any pointer.

> Let's make the following assumption: every type is implicitly derived
> from void. Many C++ programmers can accept that.

Name one. It's manifestly false; it is, in fact, illegal to
derive from void (or from any incomplete type).

Void, as a type, is an incomplete type, which can never be
completed. And in no case can you derive from an incomplete
type. The rules concerning convertion of T* to void* do NOT
obey the rules of derived to base (which only works if the types
are complete), and of course, work even in cases where
inheritance would be illegal, e.g. int* to void*.

--
James Kanze (GABI Software) email:james.kanze(a)gmail.com
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Joshua Lehrer on

James Kanze wrote:
> > In my mind, it makes sense. All types should be considered to inherit
> > (virtually) from void.
>
> What you're looking for isn't void, it's Object. In Java.
>
> Personally, I've never missed it in C++.
>

No, what I'm looking for is the ability to bind a temporary to a const
reference to void and take advantage of the C++ rules that temporaries
will remain alive as long as the const reference bound to it.

I have a lot of ScopeGuard / Lock style classes. The pattern is always
the same, create the templated subclasses, make sure they all inherit
from some empty base class, typedef "const base &" to be LOCK, then let
the user write "LOCK L = make_lock(args);"

I'm not looking for 'object' because I don't think "void" should have
any members, methods, nor should it even be a complete type.

Tell me, why is it that all pointers can degrade to void pointers, but
all references can't degrade to void references? And don't give me
"because void is not a complete type" because I can demonstrate logical
behavior:

const void & v = Lock(mx);

In the above code, a temporary Lock is constructed and bound to the
const reference 'v'. The temporary's lifetime is guaranteed to be at
least as long as the reference. The code should have identical
behavior to:

const Lock &L = Lock(mx);

In the second case, the user can call const methods on 'L'. If I want
to prevent that, I should be able to use the first case.

joshua lehrer
http://www.lehrerfamily.com/


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]