3

I am using clang power tools to compile a project which is usually compiled using visual studio.
In boost's lwm_win32.hpp header (yes we are using an old version of boost and currently cannot update) I get an error reading.

function declared stdcall here was previously declared without calling convention

the line in question is:

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

I don't get any errors or warnings for this line when compiling with visual studio. Interestingly I don't get any even if I manually change the calling convention from __stdcall to __cdecl. Clang tells me which previous declaration it has seen. By manually inspecting this location I would say clang is right. After deciphering all preprocessor defines I would also say __cdecl is what should be seen by visual studio. However, neither the official documentation for InterlockedExchange, nor the official documentation for the intrinsic do mention a specific calling convention.

So basically I am unsure what the root of the problem is. Visual studio accepting any calling convention in the declaration? Clang not seeing the correct declaration due to some preprocessor macros set to the wrong value? Boost declaring the wrong calling convention? I must admit I am confused.

Visual Studio version is 2015 Update 3.

Clang++ version is 6.0.0 called with parameter -fms-compatibility-version=19.

EDIT

As suggested in the comments I had a look at the preprocessor output of MSVC and Clang. They looked rather identical to me. For both the line from boost expands to

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

Both have

#pragma intrinsic(_InterlockedExchange)

and the declarations

long __cdecl _InterlockedExchange(long volatile * _Target, long _Value);
LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value);

as well as several inline implementations for different overloads.

In both compilers I target 32-bit (-m32 for clang).

Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42
sigy
  • 2,408
  • 1
  • 24
  • 55
  • 3
    Does MSVC actually emit a call to a library function instead of treating it as an intrinsic and inlining `lock cmpxchg`? You'd want it defined in terms of an intrinsic, because a function call takes more code-size than inlining the single instruction. – Peter Cordes Jul 13 '18 at 08:36
  • 1
    Note that "the official documentation" is for `_InterlockedExchange` - with a leading underscore - which is not a function, but the intrinsic Peter Cordes expects. `InterlockedExchange` from a DLL is something different. If you really are on boost 1.32 (like in the link), that might not be correctly configured for clang 6.0? – Bo Persson Jul 13 '18 at 08:48
  • @Peter According to the docs it does now, yes, but I think the compiler still needs to see the (appropriate) function prototype. – Paul Sanders Jul 13 '18 at 09:38
  • @PeterCordes Actually I don't know. I just noticed that MSVC compiles the code without any problem but clang++ doesn't. Would it make a difference in my case regarding the compile error? – sigy Jul 13 '18 at 13:21
  • @BoPersson True, but neither documentation mentions a calling convention. Do you mean that boost might be missing some `#ifdef`s or the like for clang 6? – sigy Jul 13 '18 at 13:23
  • Testing online, I see MSVC also issues an error message if it sees incompatible calling conventions, so I'd say either you're using MSVC in a mode in which those calling conventions are ignored (say, when compiling in 64-bit mode), or after preprocessing, the code clang sees is different from the code MSVC sees. If the latter, try inserting `#error` directives in appropriate locations to see what only gets picked up by clang / what only gets picked up by MSVC, and find out where the first significant difference is. –  Jul 13 '18 at 13:27
  • 1
    InterlockedExchange is pretty tricky, far too many headers want to define it. It matters a lot whether you target x86 or x64, the calling convention is only an x86 detail. The MSVC++ compiler just ignores it if there is a mismatch, Clang might not. Plowing through the precompiler output to find the bad declaration is probably going to be your lot. – Hans Passant Jul 13 '18 at 14:26
  • @HansPassant Which will of course be no fun at all. – Paul Sanders Jul 13 '18 at 17:25
  • @hvd I compile for 32-bit – sigy Jul 13 '18 at 21:14
  • @HansPassant Are you saying that I will *never* get a diagnostic from MSVC for mismatching calling conventions even when targeting x86? I had a look at the preprocessed outputs. Please see my updated answer. – sigy Jul 13 '18 at 21:17
  • @sigy If you encounter any problem with Clang Power Tools you can open an issue here: https://github.com/Caphyon/clang-power-tools/issues – Ionut Enache Nov 06 '19 at 13:52

1 Answers1

0

Do the clang power tools offer you things that you really don't want to live without?

If not (and I imagine that is a big if) then you might consider experimenting with VS 2017's support for clang. I have no experience of it personally and it's all still a bit new but what I do know is that MS are putting a lot of work in and it may well pay off in the long run.

As it is, I think you might be out on a bit of a limb. And whatever should and should not be in the header files, I would say that what MS say goes, wouldn't you?

Why are you stuck with that old version of boost? That might be a blocking issue here.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • 1
    Clang power tools offer me to compile (syntax only) without having to setup a separate project configuration. I just install llvm and clang power tools and can run clang on my existing projects. My company does not officially use clang but I would like to make use of all its power to double check my code for issues. I do not understand what you mean with "whatever should and should not be in the header files". – sigy Jul 13 '18 at 13:31
  • _I would like to make use of all its power to double check my code for issues_ So this is important to you? It kinda seems it's causing more problems than it is solving. What does it offer you that VS 2015 doesn't? – Paul Sanders Jul 13 '18 at 16:04
  • (Just curious). – Paul Sanders Jul 13 '18 at 17:23