Draco の status.h より先に windows.h を include するとエラーになる

環境

本題

Draco の status.h には、ERRORという列挙子が定義されています。 一方、windows.h 内で include している wingdi.h には、以下のようにERRORが define されています。

#define ERROR               0

そのため、 status.h より先に windows.h を include すると、 status.h のERROR が0に置き換えられ、ビルドエラーになります。 下記コードはビルドエラーになりますが、1行目と2行目を入れ替えるとビルドが通ります。

#include <Windows.h>
#include <draco/core/status.h>

int main() {
    return 0;
}

ちなみにエラーメッセージは以下のように表示されました。

1>C:\libs\draco\include\draco/core/status.h(28): error C2059: syntax error: 'constant'
1>C:\libs\draco\include\draco/core/status.h(28): error C3805: 'constant': unexpected token, expected either '}' or a ','

(2019/5/19追記) どうしてもこの順番で include したい場合は、#undef ERRORを使用する方法が考えられます。 ただし windows.h のマクロが無効になります。

#include <Windows.h>
#undef ERROR
#include <draco/core/status.h>

int main() {
    printf("ERROR = %d", draco::Status::ERROR); // -1
    //printf("ERROR = %d", ERROR); // コンパイルエラー
    return 0;
}

windows.h のマクロを有効にしたい場合は、#pragma push_macro及び#pragma pop_macroを使う方法があります。 ただしその場合は Draco のERROR列挙子が使用できません。

#include <Windows.h>
#pragma push_macro("ERROR")
#undef ERROR
#include <draco/core/status.h>
#pragma pop_macro("ERROR")

int main() {
    //printf("ERROR = %d", draco::Status::ERROR); // コンパイルエラー
    printf("ERROR = %d", ERROR); // 0
    return 0;
}

参考

Error enum in status.h collides with error define on Windows in wingdi.h · Issue #499 · google/draco · GitHub