What is the main differences between void and other incomplete types in C++?

216 views Asked by At

I'm new at programming overall.

I've tried reading the official standard for the language, but couldn't find any answers to my question.

so I need to understand what is the main differences between void type and other incomplete types in C++. For example: are there places in the language (or code) where we can use void but not other incomplete types, or vice versa? Or is void just like other incomplete types in every way?

1

There are 1 answers

1
Christophe On BEST ANSWER

There is indeed a very subtle difference between void and another incomplete type:

You can't have a reference to a void type:

struct T;       // incompletely defined type 
                // incompletely defined types and void are incomplete types
T* x=nullptr;   // pointer to incomplete type are valid, same for void pointers
T& tref=*x;     // it's valid to have a reference to an incompletely defined type 
void& vref;     // it's INVALID to have a reference to void, because no object could ever be void

 int f(void &vt);   // INVALID function declaration with invalid parameter: void reference 
 int g(T& vt);      // valid function declaration using a parameter: reference to incomplete type

C++ Standard quotes:

3.9/5: A class that has been declared but not defined, or an array of unknown size or of incomplete element type, is an incompletely-defined object type. Incompletely-defined object types and the void types are incomplete types

3.9/8: An object type is a (possibly cv-qualified) type that is not a function type, not a reference type, and not a void type.

8.3.2/1: A declarator that specifies the type “reference to cv void” is ill-formed.

It is possible to convert any expression to void, which is obviously not the case for other incomplete types:

(void)(3 + 5);    // OK explicit conversion to void
(T)(3 + 5);       // Invalid expression to an incomplete type

This is documented in the C++ Standard:

3.9.1/9: Any expression can be explicitly converted to type cv void