Why does my C++/WinRT project get errors of the form “consume_Something: function that returns ‘auto’ cannot be used before it is defined”?

Raymond Chen

Raymond

Last time, we investigated a mysterious error that occurs when linking a C++/WinRT project, and I noted that there’s some good news and some bad news. The good news is that this error message is going away. The bad news is that it’s being replaced with a different error message that you have to learn.

Let’s take another look at the code that triggers this error.

#include <winrt/Windows.Gaming.Input.h>

void CheckGamepads()
{
    auto gamepads =
        winrt::Windows::Gaming::Input::Gamepad::Gamepads();
    for (auto&& gamepad : gamepads)
    {
        check(gamepad);
    }
}

Instead of getting a linker error, you get a compile-time error at the point you attempt to consume an interface whose header file you failed to include.

test.cpp(7): error C3779: winrt::impl::consume_Windows_Foundation_Collections_IIterable<D,winrt::Windows::Gaming::Input::Gamepad>::First': a function that returns 'auto' cannot be used before it is defined
with
[
    D=winrt:::Windows:::Gaming:::Input:::Gamepad
]
note: see declaration of 'winrt::impl::consume_Windows_Foundation_Collections_IIterable<D,winrt::Windows::Gaming::Input::Gamepad>::First'
with
[
    D=winrt::Windows::Gaming::Input::IVisualCollection
]

For the impatient: The problem is that you are missing the header file for the interface you are using. In this case, we are using Windows.Foundation.Collections.IIterable, so we need to include

#include <winrt/Windows.Foundation.Collections.h>

You can read the pull request that makes the change to detect the error at compile time rather than link time.

The trick is that the forward-declared methods are declared as returning auto with no trailing return type and no body. This means “I want the compiler to deduce the return type (but I’m not giving any clues yet).” If you try to call the method before the method has been implemented, then the compiler reports an error because it doesn’t yet have the necessary information to determine the return type.

Hopefully the new error message will make it easier to figure out what went wrong. At least it gives you a file name and line number that points to the place where the unimplemented method is used, and the error mesage includes the name of the type whose definition is missing.

 

Raymond Chen
Raymond Chen

Follow Raymond   

5 Comments
Avatar
George Gonzalez 2019-05-30 09:01:05
A nitpicker could pick that the new message STILL requires one to think like a compiler, and know that an undeclared interface causes the compiler to generate an auto return type, is that right?   The message, like the old Lance Lawson comic strip, always has the criminal's alibi saying or assuming too much.  How about a stream of conciousness error message explaing the compiler's chain of thought, like "Compiler sees xxxx on line yyy.  No expllicit definition seen so far for xxxx return type or parameters.   Compiler assuming auto return type.  However  in this context compiler cannot deduce the type at the point of call, so that's an error.  Give the compiler a hint of what xxxx is."
Avatar
Ian Kemp 2019-06-02 23:28:10
Why not make it even clearer with a short addition: a function that returns 'auto' cannot be used before it is defined (did you forget to include a relevent header file?)
Avatar
Michael Ratanapintha 2019-06-09 17:53:47
Unfortunately the linked change to C++/WinRT to produce the better error message is gone, at least for the moment: https://github.com/microsoft/xlang/pull/436