While working on a project using nnvg
, I discovered that my code built perfectly with GCC, but would fail to build with MSVC. The error was in the generated header file for uavcan.si.unit.pressure.Scalar.1.0
. Given the following struct declaration:
typedef struct
{
/// saturated float32 pascal
float pascal; /* Line 86 */
} uavcan_si_unit_pressure_Scalar_1_0;
MSVC was reporting a syntax error at the declaration of float pascal
(followed by about a million more errors):
....\out\uavcan\si\unit\pressure\Scalar_1_0.h(86): error C2059: syntax error: ';'
I was quite puzzled by this for several hours. After much digging, I found that some of my code was including Windows.h before including all the generated headers. It turns out that minwindef.h, which is included by Windows.h, contains the following:
#if (!defined(_MAC)) && ((_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED))
#define pascal __stdcall
#else
#define pascal
#endif
Thus, after the preprocessor stage, the declaration was changed from float pascal;
to float __stdcall;
, which does indeed result in invalid syntax at the semicolon. Naturally, this was trivially fixed by adding #undef pascal
after including Windows.h. However, since this include was in code which I cannot modify, I instead resorted to copying the default C templates for nnvg
and adding #undef pascal
to base.j2.
As I could find almost no evidence online that this pascal
macro existed in the first place, and furthermore, I could find no evidence that anyone had run into this with nunavut before, I thought it best to make this post for future readers who may encounter the same headache I did.
My environment:
- Windows 10
- Visual Studio 2022 (Professional)
- MSVC version 19.34.31937.0
- Windows 10 SDK version 10.0.22621.0