December 27th, 2023

What does it mean when the compiler says that it can’t convert something to itself?

A customer encountered a very strange error message from the Visual C++ compiler:

oops.cpp(7): Error C2664: 'void something(blah)' cannot convert argument 1 from 'blah' to 'blah'

Why is the compiler complaining that it cannot convert a blah to a blah? How is it not possible to convert something to itself?

The answer is given in the next line of the error message:

oops.cpp(7): note: use of undefined type 'blah'

Here’s a sample program that demonstrates the problem.

struct blah;

void something(blah);

void test(blah& b)
{
    something(b); // error here
}

The problem is that the test function is passing a blah object by value to the something function. This requires the compiler to convert the thing you passed (a blah object) to the thing the function accepts (a blah object), which would normally be accomplished by using the copy constructor. But the compiler can’t find a copy constructor for blah, so it complains.

Now, the reason it can’t find a copy constructor is that the type blah has never been defined. All that exists is a forward reference. That’s what the second error message is trying to tell you: “You said blah, but I don’t know anything about blah.”

Bonus chatter: Other compilers produce slightly less confusing error messages by complaining about the incompleteness first.

// gcc
oops.cpp:7:15: error: invalid use of incomplete type 'struct blah'
oops.cpp:1:8: note: forward declaration of 'struct blah'

// clang
oops.cpp:11:15: error: argument type 'blah' is incomplete
oops.cpp:1:8: note: forward declaration of 'blah'

// icc
oops.cpp(11): error: cannot convert to incomplete class "blah"
Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

1 comment

Discussion is closed. Login to edit/delete existing comments.

  • alan robinson

    This is actually an excellent general Life lesson. When one source is confusing try another source for greater context. Trying other compilers is a really good way to see what might be wrong and whether or not it really is somehow a bug.

    But in the grander context if you're trying to learn a new concept and the textbook that's been assigned or you have access to is confusing look up the context in another...

    Read more