Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't void take a void value in C++?

I'm curious why C++ does not define void via :

typedef struct { } void;

I.e. what is the value in a type that cannot be instantiated, even if that installation must produce no code?

If we use gcc -O3 -S, then both the following produce identical assembler :

int main() { return 0; }

and

template <class T> T f(T a) { }
typedef struct { } moo;
int main() { moo a; f(a); return 0; }

This makes perfect sense. A struct { } simply takes an empty value, easy enough to optimize away. In fact, the strange part is that they produce different code without the -O3.

You cannot however pull this same trick with simply typedef void moo because void cannot assume any value, not even an empty one. Does this distinction have any utility?

There are various other strongly typed languages like Haskell, and presumably the MLs, that have a value for their void type, but offer no valueless types overtly, although some posses native pointer types, which act like void *.

like image 823
Jeff Burdges Avatar asked Apr 02 '12 00:04

Jeff Burdges


2 Answers

I see the rationale for void being unable to be instantiated coming from the C roots of C++. In the old gory days, type safety wasn't that big a deal and void*s were constantly passed around. However, you could always be looking at code that does not literally say void* (due to typedefs, macros, and in C++, templates) but still means it.

It is a tiny bit of safety if you cannot dereference a void* but have to cast it to a pointer to a proper type, first. Whether you accomplish that by using an incomplete type as Ben Voigt suggests, or if you use the built-in void type doesn't matter. You're protected from incorrectly guessing that you are dealing with a type, which you are not.

Yes, void introduces annoying special cases, especially when designing templates. But it's a good thing (i.e. intentional) that the compiler doesn't silently accept attempts to instantiate void.

like image 104
bitmask Avatar answered Sep 22 '22 15:09

bitmask


Because that wouldn't make void an incomplete type, now would it?

Try your example code again with:

struct x; // incomplete
typedef x moo;
like image 32
Ben Voigt Avatar answered Sep 23 '22 15:09

Ben Voigt