对于Clang ++,InterlockedExchange的32位调用约定错误,但是MSVC可以

时间:2018-07-13 08:29:49

标签: c++ visual-studio clang++ intrinsics calling-convention

我正在使用clang power tools来编译通常使用Visual Studio编译的项目。在boost's lwm_win32.hpp header中(是的,我们使用的是Boost的旧版本,目前无法更新),我在阅读

时出错
  

在这里声明为“ stdcall”的函数以前是在没有调用约定的情况下声明的

该行是

extern "C" __declspec(dllimport) long __stdcall InterlockedExchange(long volatile *, long);

使用Visual Studio编译时,此行没有任何错误或警告。有趣的是,即使手动将调用约定从__stdcall更改为__cdecl,我也一无所获。 Clang告诉我它之前看过哪个声明。通过手动检查此位置,我会说c是正确的。解密所有预处理器定义之后,我还要说__cdecl是Visual Studio应该看到的。但是,official documentation for InterlockedExchangeofficial documentation for the intrinsic都没有提到特定的调用约定。

所以基本上我不确定问题的根源是什么。 Visual Studio在声明中接受任何调用约定吗?由于某些预处理器宏设置为错误的值,导致Clang无法看到正确的声明? Boost声明了错误的调用约定?我必须承认我很困惑。

Visual Studio版本为2015 Update 3。

使用参数-fms-compatibility-version=19调用的Clang ++版本是6.0.0。

编辑

正如评论中建议的那样,我看了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位(clang为-m32)。

1 个答案:

答案 0 :(得分:0)

clang电动工具会为您提供您确实不想要的东西吗?

如果没有(我想那是很大的话),那么您可以考虑尝试使用VS 2017对clang的支持。我个人没有经验,它仍然有些新,但是我知道MS正在投入大量工作,从长远来看很可能会有所收获。

就目前而言,我认为您可能会有些失落。头文件中应该包含和不应该包含的内容,我会说MS所说的,不是吗?

为什么您会继续使用旧版本的boost?这可能是一个阻碍性的问题。