Reputation: 19431
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?
Upvotes: 1
Views: 3011
Reputation: 340218
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:
Upvotes: 3