From: Lucian Radu Teodorescu on

Frederick Gotham wrote:
> There's no such thing as a "reference to void" because there's no such
> thing as an object whose type is "void", and therefore a reference cannot
> be bound to such a hypothetical object. Consider:
>
> void i;
>
> void &j = i;
>

Of course there is no object that has the type void. It doesn't have to
be.

Please take a look at the following code:

<code>

class A {};
class Void; // No definition

int main()
{
A a;
Void* p = reinterpret_cast<Void*>( &a );
Void& ref = *p;

A& refA = reinterpret_cast<A&> (ref);

return 0;
}

</code>

Here, there is no object of type Void. But still I can create a
reference to Void, and the use it. Of couse, I can only cast from it,
because I don't have an interface for the type Void.

Why shouldn't the "void" type behave just like this "Void" ?

Best Regards,
Lucian Radu Teodorescu


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

From: James Kanze on
Alf P. Steinbach wrote:
> * James Kanze:
> > 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).

> Note that Lucian (as I read that article, especially in light
> of the rest of it) was describing a future extension, not the
> current language.

I understand that. He also makes some assumptions with regards
to the current language, to argue that the extention is
intuitively natural, and would easily fit into the current
language.

I can easily see some interest in such an extension. They way
he describes it, however (all types deriving from void) isn't
compatible with the way the current language is described, and
would require a major rework of the standard (even if the
effective results for the user are the same).

--
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
Seungbeom Kim wrote:
> James Kanze wrote:
> > 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.

> Allowing reference to void doesn't allow creating an object of type
> void; it just allows to refer to an existing object through a supertype.
> Reference to Base is allowed even if Base is an abstract base class and
> no complete object of Base can exist; in what regard does reference to
> void differ?

A reference to Base always designates an object of type Base.
Maybe a sub-object---if Base is abstract, the necessarily a
sub-object. But something of type Base.

Nothing of type void can exist, so the reference cannot refer to
something of type void, not even a sub-object.

> What loopholes do you think could it open?

Nothing in particular. Only that it breaks the current
definition of references. I think that it's probably doable,
but it involves a good deal of reflection and work, and I don't
really see any great benefit.

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

> Sort of. I'm not sure if you can create an object of type Object in
> Java, but the proposal doesn't ask to allow creating an object of type
> void in C++, anyway.

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

> Yes, what you've never missed can be what's a real pain in someone
> else's neck. :-) Disagreement to the proposal would be more convincing
> with an argument of possible loopholes in the type system, or breaking
> existing codes [which I don't expect].

I think the shoe is on the other foot. You're talking about
messing around with the C++ object model. It's not a question
of "no reason not to"; it's a question of strong reasons for.
And I can't see any.

--
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: Andrei Polushin on
Lucian Radu Teodorescu wrote:
> IMHO it's worse to have all kind of exceptions in the language, than to
> have one good rule that works in (almost) all cases. In this case, as
> you noticed currently "void" isn't really a type, and isn't really a
> syntactic placeholder. And the bad thing about this duality is the fact
> that we don't know the exact border of this: sometimes void behaves
> like a type and we can have pointers to void, and sometimes void
> doesn't behave like a type and doesn't allow us to have references of
> type void.
>
> Here is an example:
> <code>
>
> template <typename T>
> struct Test
> {
> typedef T original_type;
> typedef T* pointer_type;
> typedef T& reference_type;
> };
>
> class A {};
>
> bool b1 = boost::is_same<int, void>::value;
> bool b2 = boost::is_same<int, Test<void>::original_type>::value; // (2)
> Error here?
> bool b3 = boost::is_same<int, Test<A>::original_type>::value;
>
> </code>
>
> Is there something wrong with the definition of the Test class
> template? Am I doing something wrong when I try to instantiate
> Test<void>, when I need the original type? Why should the creator of
> the template have to think of the "void exception" when he is building
> his class?

Actually, you can look at the definition of std::allocator - it has
been explicitly specialized for void. I suspect it was a workaround.

Another sort of workaround (adapted from <boost/operators.hpp>):

struct void_t {}; // I have to introduce another empty type

template <class T, class baseT = void_t>
struct incrementable : baseT {
friend T operator++(T& x, int) {
T temp(x);
++x;
return temp;
}
};

The definition of void lacks for generalization, so it couldn't work
well with generic programming. We may expect more flaws as far as
generic programming evolves.


--
Andrei Polushin


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

From: Lucian Radu Teodorescu on

James Kanze wrote:
> Seungbeom Kim wrote:
> > Allowing reference to void doesn't allow creating an object of type
> > void; it just allows to refer to an existing object through a supertype.
> > Reference to Base is allowed even if Base is an abstract base class and
> > no complete object of Base can exist; in what regard does reference to
> > void differ?
>
> A reference to Base always designates an object of type Base.
> Maybe a sub-object---if Base is abstract, the necessarily a
> sub-object. But something of type Base.
>
> Nothing of type void can exist, so the reference cannot refer to
> something of type void, not even a sub-object.

Again I'm considering an hypothetical world in which every C++ type is
derived from void. In this case void would be an empty type (do data is
passed to the derived classed), and the compiler disallows to create
objects of types void. But this doesn't imply that the compiler
shouldn't allow object of types derived from void.

If a type (let's name it Derived) is derived from void, and we have an
object of type Derived, we can hold a void reference to that object
because the reference designates a sub-object of our object. It's just
like the following situation:

class Void { /*disallow construction of an object of this type*/ };

class Derived : public Derived {};

Derived d;
Void& r = d;

I still can't see how does Void of this example differs from void in my
assumtion (cannot be instantiated, base of all other objects). Is there
something that I am missing?

> > What loopholes do you think could it open?
>
> Nothing in particular. Only that it breaks the current
> definition of references. I think that it's probably doable,
> but it involves a good deal of reflection and work, and I don't
> really see any great benefit.
> [...]
> I think the shoe is on the other foot. You're talking about
> messing around with the C++ object model. It's not a question
> of "no reason not to"; it's a question of strong reasons for.
> And I can't see any.
>

Ok. Here I must admit that you are right. The benefits are not too
many, and I can't find strong reasons for a C++ change proposal. I was
trying to find out a good reason why references to void aren't allowed,
not to make a change proposal.

Thank you,
Lucian Radu Teodorescu


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