我正在使用clang 电动工具来编译一个通常使用 Visual Studio 编译的项目。
在boost 的 lwm_win32.hpp 头文件中(是的,我们使用的是旧版本的 boost,目前无法更新)我得到一个错误读数。
此处声明的函数
stdcall
先前已在没有调用约定的情况下声明
有问题的行是:
extern "C" __declspec(dllimport) long __stdcall InterlockedExchange(long volatile *, long);
使用 Visual Studio 编译时,我没有收到任何错误或警告。有趣的是,即使我手动将调用约定从__stdcall
to更改为__cdecl
. Clang 告诉我它看到了哪个先前的声明。通过手动检查这个位置,我会说 clang 是正确的。在破译所有预处理器定义后,我还要说__cdecl
的是视觉工作室应该看到的。但是,InterlockedExchange的官方文档和内在函数的官方文档都没有提到特定的调用约定。
所以基本上我不确定问题的根源是什么。Visual Studio 接受声明中的任何调用约定?由于某些预处理器宏设置为错误的值,Clang 没有看到正确的声明?提升声明错误的调用约定?我必须承认我很困惑。
Visual Studio 版本是 2015 Update 3。
Clang++ 版本是 6.0.0,使用参数调用-fms-compatibility-version=19
。
编辑
正如评论中所建议的,我查看了 MSVC 和 Clang 的预处理器输出。他们看起来和我差不多。对于这两条线从 boost 扩展到
extern "C" __declspec(dllimport) long __stdcall _InterlockedExchange(long volatile *, long);
都有
#pragma intrinsic(_InterlockedExchange)
和声明
long __cdecl _InterlockedExchange(long volatile * _Target, long _Value);
LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value);
以及针对不同重载的几个内联实现。
在这两个编译器中,我的目标都是 32 位(-m32 表示 clang)。