visual-c++visual-c++-2008

wchar_t is not treated as built-in type even when the option is enabled


So here is the preprocessed output of a struct:

typedef struct RPT_Item
{
    wchar_t *fullPath; 
    RPT_ItemFlags_t itemFlags; 




    int isComposite;
    const void *reserved; 
} RPT_Item_t;

Visual Studio complains because wchar_t is not defined, its own cryptic way:

error C2016: C requires that a struct or union has at least one member  

I looked at the project files and also at the particular C file where the error appears and I can confirm that "Treat wchar_t as built-in type is set to YES".

If I define the type using a typedef it compiles fine.

I used the preprocessor output so I can exclude that some nasty preprocessor #define trick play the main role.

This project contains many low-level hacks, for example the CRT is not linked (/NODEFAULTLIB).

Most of the code is not written by me, and I'm tasked to remove reference to wchar.h from a public header that uses wchar_t, because VS treats it as a built in type default. (This particular module is built only on Windows.)

I totally ran out of ideas. Is there a compiler option or a pragma that can interfere? Or could it be even a compiler bug?


Solution

  • Microsoft didn't explicitly document this until VS 2013, but the docs for /Zc:wchar_t says

    The wchar_t type is not supported when you compile C code.

    It seems that including nearly any header from the runtime or from the SDK will typedef wchar_t tounsigned short using the following sequence:

    #ifndef _WCHAR_T_DEFINED
    typedef unsigned short wchar_t;
    #define _WCHAR_T_DEFINED
    #endif
    

    you might want to do something similar in your file that uses wchar_t.

    Note that when compiling a C++ file, if /Zc:wchar_t is in effect then the compiler pre-defines _WCHAR_T_DEFINED. If /Zc:wchar_t- is in effect it doesn't - so the above snippet should work nicely with C++ as well (for MSVC anyway - I don't know how other compilers might deal with this if you're looking for something portable).

    The _WCHAR_T_DEFINED macro is documented: