From: Lucian Radu Teodorescu on 26 Oct 2006 06:33 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 26 Oct 2006 10:29 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 26 Oct 2006 10:37 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 26 Oct 2006 11:38 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 26 Oct 2006 13:30
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! ] |