April 6th, 2026
0 reactions

Learning to read C++ compiler errors: Illegal use of -> when there is no -> in sight

A customer reported a problem with a system header file. When they included ole2.h, the compiler reported an error in oaidl.h:

    MIDL_INTERFACE("3127CA40-446E-11CE-8135-00AA004BB851")
    IErrorLog : public IUnknown
    {
    public:
        virtual HRESULT STDMETHODCALLTYPE AddError( // error here
            /* [in] */ __RPC__in LPCOLESTR pszPropName,
            /* [in] */ __RPC__in EXCEPINFO *pExcepInfo) = 0;
        
    };

The error message is

oaidl.h(5457,43): error C3927: '->': trailing return type is not allowed after a non-function declarator
oaidl.h(5457,43): error C3613: missing return type after '->' ('int' assumed)
oaidl.h(5457,43): error C3646: 'Log': unknown override specifier
oaidl.h(5457,43): error C2275: 'LPCOLESTR': expected an expression instead of a type
oaidl.h(5457,43): error C2146: syntax error: missing ')' before identifier 'pszPropName'
oaidl.h(5459,60): error C2238: unexpected token(s) preceding ';'

The compiler is seeing ghosts: It’s complaining about things that aren’t there, like -> and Log.

When you see the compiler reporting errors about things that aren’t in the code, you should suspect a macro, because macros can insert characters into code.

In this case, I suspected that there is a macro called AddError whose expansion includes the token ->.

The customer reported that they had no such macro.

I asked them to generate a preprocessor file for the code that isn’t compiling. That way, we can see what is being produced by the preprocessor before it goes into the part of the compiler that is complaining about the illegal use of ->. Is there really no -> there?

The customer reported back that, oops, they did indeed have a macro called AddError. Disabling the macro fixed the problem.

The compiler can at times be obtuse with its error messages, but as far as I know, it isn’t malicious. If it complains about a misused ->, then there is probably a -> that is being misused.

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

Sort by :
  • Melissa P 2 hours ago

    wouldn't be the worst idea if the compiler reports that there is a macro

    sure, a preprocessor is doing the text replacement but the preprocessor already adjusts line and column positions otherwise macros and debugging together would never work, so the compiler should have the information available to say "I expect something like -> and I am currently inside a something, like a macro definition"; we already solved a similar issue with #inline backtracking, where a compiler prints inlined by, inline by, inline by ... or the notorious template "de-obfusctors"....

    I blame clang for turning crypto-error messages into readable color-coded "Expressive...

    Read more