Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11: reference-to-void?

Tags:

c++

c++11

Is this C++11 program ill-formed?

typedef void& rv;

int main() {}

I couldn't find anything disallowing it in the standard (looked in 3.9.2 and 8.3.2).

Clang says "cannot form a reference to 'void'", gcc says "cannot declare reference to ‘void’"

I would have expected [dcl.ref]/5 to give such a restriction, if it were intended.

Are the implementations just "reading between the lines" because such a type can never be used in an object definition?

like image 597
Andrew Tomazos Avatar asked Oct 09 '13 02:10

Andrew Tomazos


People also ask

Can you reference a void in C++?

You can - by casting - but the compiler can't. A reference to a void sufferes from the same problem, by definition the data pointed to doesn't have a type, therefore it can't be referenced in any meaningful way. To reference it you - the programmer - need to cast it to another type, then you can have a typed reference to it.

Which declarator specifies the type reference to CV void?

A declarator that specifies the type “ reference to cv void ” is ill-formed. As a side tidbit of info, this rule has been taken advantage by the N3421 greater<> proposal (which was already accepted to be included into the future C++14 standard) by having void as the default template argument. B.

Why can't I use a void pointer as a reference?

When using a void pointer, you're not allowed to dereference it; transposed to the case of references, that means you can't use the (always hypothetical) void reference. So

What is the use of anyreference to void in Java?

reference to void has a useful property of being used as a generic reference argument in a constructor. So you can have Foo a(anyReference) and it could internally convert it to a void pointer. It in turn allows you to pass references and the constructor can take care of casting it to a pointer for you.


1 Answers

Quoting from the C++11 standard (emphasis mine):

8.3.2 References

1 [...] A declarator that specifies the type “reference to cv void” is ill-formed.


As a side tidbit of info, this rule has been taken advantage by the N3421 greater<> proposal (which was already accepted to be included into the future C++14 standard) by having void as the default template argument.

B. The technique of using default template arguments and explicit specializations for void was chosen for its non-intrusiveness. greater<void> isn't valid C++11 (it would attempt to form a reference to void, forbidden by 8.3.2 [dcl.ref]/1). Additionally, while users are permitted to specialize Standard Library machinery (17.6.4.2.1 [namespace.std]/1), such specializations must involve user-defined types.


Maybe I'm just a bit more indulged into these mind games, but for the rationale of why this rule is enforced -- and I must state that this is just my own humble opinion -- consider the following code:

sizeof(double&);   // Results in double's size

using foo_ref = foo&;
sizeof(foo_ref);   // Results in foo's size

sizeof(void);      // Error! void has no size!
sizeof(void&);     // Error! Tries to get the size of void

Most importantly, keep in mind that references are just aliases of other objects, and you cannot have an object of type void.

like image 72
Mark Garcia Avatar answered Oct 26 '22 07:10

Mark Garcia