From: James Kanze on
Frederick Gotham wrote:
> Joshua Lehrer posted:

> > No, what I'm looking for is the ability to bind a temporary to a const
> > reference to void

> There's a such thing as:

> (1) a reference to const
> (2) a reference to non-const

> , but there's no such thing as a const reference.

Yes, but for better or worse, this misnomer has established
itself. In a similar way, people usually speak of T const* as a
const pointer, although it is the pointed to that is const, and
not the pointer. It's probably regrettable, but the usage is
too well established to change.

> int &const i = whatever; /* Compiler ERROR */

> > and take advantage of the C++ rules that temporaries
> > will remain alive as long as the const reference bound to it.

> If you bind a "reference to const" to an R-value, then the
> following two are equivalent:

> int const &i = 5;

> and:

> int const __lit = 5;

> int const &i = __lit;

> (i.e. the temporary object has the same scope as the reference.)

Or longer. If the reference is a function parameter, for
example.

> > Tell me, why is it that all pointers can degrade to void pointers, but
> > all references can't degrade to void references?

> All pointer types can implicitly convert to void* (apart from function
> pointers, and member function pointers).

> 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;

On the other hand:

int i ;
void* pi = &i ;
void& ri = *pi ;

It's not currently legal, but there's a certain logical sense to
it. (Of course, there are also reasons why it isn't legal, and
it would take some work to make it legal. But maybe less that
it would appear at first glance.)

> > And don't give me
> > "because void is not a complete type" because I can demonstrate logical
> > behavior:

> > const void & v = Lock(mx);

> Is that hypothetical code. . .

It's hypothetical code. Of course, in this case, I don't see
much point in the void&; what does it buy us over simply:

Lock const v( mx ) ;

If instead of Lock, we used a function, and its return value,
perhaps. But even then, we presumably know the return type, so
there's no point in not naming it. (In fact, naming it means
that if I happen to mistype the name, and hit the name of
another function, which returns a different type, I get an error
message; declaring it as void is less safe.)

Interestingly, the example is, IMHO, an argument for anonymous
variables. Supposing that Lock and mx mean what I think they
do, he's had to invent a name which will never be used again in
the function.

--
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:
> 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 which case, what's the point. It's a hypothetical world so
far removed from reality as to be irrelevant with regards to
C++.

If you are suggesting such a proposal for possible
standardization, it practically breaks the basic C++ object
model. And because of this, will find almost no support.

If your only goal is to allow void references, there are a lot
simpler ways of doing it; I don't think you'd have to break
*that* much. But I do think that you have to realize what you
are breaking, and consider the effects of it.

> 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.

I'm not sure if you're proposing allowing explicitly:

class MyClass : public void { ... } ;

here, but if so, I'd be very surprised that it would fly.

Given the current C++ memory model and object model, I don't
think you can fit void into it without either a major rework
(which nobody really wants), or without adding an exception
almost everywhere for void.

Again, I don't think such an extreme step is necessary for void
references. We already have references to incomplete types, and
more generally lvalues which designate incomplete types. void
is currently defined as an incomplete type. Conversions
involving pointers to void are well defined, and conversions
involving references are almost always defined in terms of the
corresponding pointer conversion. So I'd say that you've got a
starting point; you still have some work to do, but a lot less
than if you try to rewrite the entire C++ object model.

> 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.

I think you're trying the wrong approach.

The fact that you can't have references to void today is a
consequence of the fact that an lvalue must designate an object,
and you cannot have an object with type void. This is, however,
a somewhat special rule, since an lvalue may designate an object
of a different type than the type of the lvalue expression. And
we already have a number of rules concerning what you can do
with references to incomplete types, and also with references to
non-constructed types; i.e. raw memory. I suspect that if it is
important to you, somewhere in there, you could find room for
references to void. (In doing so, I suspect that in fact,
you'll want to create the concept of an lvalue of void type---if
you have references to void, it would be nice to be able to
initialize them with *p, where p is a void*, and currently,
dereferencing a void pointer is also illegal.)

> It's just like the following situation:

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

You can't derive from an object which cannot be constructed:-).
I think you're being careless in your wording.

> 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?

To begin with, it's not a base of unsigned char:-). There's
also the fact that it has non-zero size, and that sizeof(Void)
is guaranteed to be >= 1. (A type void is not a valid argument
of sizeof.) More fundamentally, you have an object, in the
sense C++ uses this word, which meets all of the requirements
spelled out in the C++ object model. I don't think you want
this; in fact, I'm almost sure you don't.

Void doesn't fit into the C++ object model (which supposes that
at the lowest level, all objects consist of one or more "bytes",
and that these bytes can be viewed as unsigned char).

> > > 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.

I don't think it would be that impossible. The main reason they
aren't allowed now, I think, is that a reference must designate
a valid object, and there are no valid objects (or sub-objects)
of type void. At any rate, that sounds like a logical
justification to me. If a need for void references is felt,
however, given the definition of void as an incomplete type, and
the other aspects I mentioned above, I think it could be made to
fit into the standard. My real objection is the idea that void
is somehow a "base" of all other types; one could imagine an
object model in which this were the case, but it isn't the
object model that is currently used in the C++ standard.

--
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
From: Gennaro Prota on
On 28 Oct 2006 11:36:22 -0400, James Kanze wrote:

>It's hypothetical code. Of course, in this case, I don't see
>much point in the void&; what does it buy us over simply:
>
> Lock const v( mx ) ;
>
>If instead of Lock, we used a function, and its return value,
>perhaps. But even then, we presumably know the return type, so
>there's no point in not naming it. (In fact, naming it means
>that if I happen to mistype the name, and hit the name of
>another function, which returns a different type, I get an error
>message; declaring it as void is less safe.)
>
>Interestingly, the example is, IMHO, an argument for anonymous
>variables. Supposing that Lock and mx mean what I think they
>do, he's had to invent a name which will never be used again in
>the function.

Hmm... how would that be different from

Lock const( mx );

? FWIW, and to keep your anti-obfuscation radar fit ;-), my SHA-1
implementation has the following:

const sha1_loop /* loop */ ( state, block );

Opinions/suggestions/insults? (I know that I could just use a static
function, but I'm not convinced that that is an improvement)

--
Gennaro Prota
(To mail me, please remove any 'u' from the provided address)

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

From: Frederick Gotham on
James Kanze:

> Yes, but for better or worse, this misnomer has established
> itself. In a similar way, people usually speak of T const* as a
> const pointer, although it is the pointed to that is const, and
> not the pointer.


Not me. I always speak of either a "const pointer" or a "pointer to const".


> It's probably regrettable, but the usage is
> too well established to change.


I'm not afraid to go against the grain when it comes to well-established
wrongs.

--

Frederick Gotham

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

From: Francis Glassborow on
In article <1162047140.568184.80310(a)b28g2000cwb.googlegroups.com>, James
Kanze <james.kanze(a)gmail.com> writes
>Yes, but for better or worse, this misnomer has established
>itself. In a similar way, people usually speak of T const* as a
>const pointer, although it is the pointed to that is const, and
>not the pointer. It's probably regrettable, but the usage is
>too well established to change.

No, no, no. The use of const reference is relatively harmless because
there is no real possibility of confusion in C++ where a reference is
not reseatable. However the issue with pointers is completely different;
a const pointer, a pointer to const and a const pointer to const are
different things and must not be confused as all exist.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' and "You Can Program in C++"
see http://www.spellen.org/youcandoit
For project ideas and contributions:
http://www.spellen.org/youcandoit/projects


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