Search code examples
c++voidincomplete-type

Why can't an incomplete type be casted to void?


Why does the following code give the following error?

Why does the type need to be complete in order to be casted to void?

struct Incomplete;
class Class
{
    virtual void foo(Incomplete &incomplete)
    {
        (void) incomplete;
        throw std::logic_error("not implemented");
    }
};

Error:

error C2027: use of undefined type 'Incomplete'  
    see declaration of 'Incomplete'

Solution

  • It's a change between C and C++, where Microsoft previously implemented the C rules. As noted in remyabel's answer, that has since been fixed.

    In C, a cast to void, or simply using an expression as a statement by itself (as in incomplete;), still involves the lvalue-to-rvalue conversion. C calls it slightly differently, but it's the same conversion.

    In C++, a cast to void, or simply using an expression as a statement by itself doesn't involve the lvalue-to-rvalue conversion. This is needed because C++ makes assignment operators return lvalues, so if the lvalue-to-rvalue conversion were applied, then

    volatile int i;
    i = 1;
    

    would not merely store, it would also immediately load afterwards.

    The lvalue-to-rvalue conversion requires a complete type, even if the value is then discarded, since otherwise, it's impossible to know how many bytes should be read.