[llvm-dev] Disabling inline compilation (Clang with VS2019)

Eric Astor via llvm-dev llvm-dev at lists.llvm.org
Wed Sep 22 05:53:18 PDT 2021


I've transferred John's example into Compiler Explorer, which will
hopefully be a useful demonstration. Both clang and MSVC handle the
dllexport case identically... but they do differ in the dllimport case:
https://godbolt.org/z/vTrEevY8o

Just as John suggested, disassembling the output shows that clang is
inlining this function, even at -O1, where MSVC doesn't, even at /O3.

I'd agree that this isn't a great match, though it *is* a point of
ambiguity in the handling of __declspec(dllimport).

One possible workaround: add a noinline marker on functions defined in
headers that need to access protected members. (
https://godbolt.org/z/Pe67ovMnP)
IMO, the best option would be to just adopt the policy that you don't
define DLL_API functions in headers... which I would suggest is the best
option anyway, since you don't want your importing code to have the
definition.

Either way, we should probably decide how we want clang to behave in this
case. It's possible we should treat anything marked as
__declspec(dllimport) as defined externally, and ignore any definition
present in the source code?

On Wed, Sep 22, 2021 at 8:33 AM Dimitry Andric via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> On 22 Sep 2021, at 14:22, John Emmas via llvm-dev <llvm-dev at lists.llvm.org>
> wrote:
> >
> > Hi there - I first asked this question over on clang-users but I got
> advised to ask it here (sorry about the length...)
> >
> > I'm a VS2019 user and I've been trying to switch it here to use Clang as
> the compiler, rather than MSVC. But I seem to have hit a common problem.
> Consider the following code:-
> >
> > #if defined (BUILDING_DLL)
> >  #define DLL_API __declspec(dllexport)
> > #else
> >  #define DLL_API __declspec(dllimport)
> > #endif
> >
> > namespace Gtkmm2ext {
> >
> >  class DLL_API Keyboard
> >  {
> >    public:
> >      Keyboard ();
> >      ~Keyboard ();
> >
> >      static Keyboard& get_keyboard() { return *_the_keyboard; }
> >
> >    protected:
> >      static Keyboard* _the_keyboard;
> >  };
> >
> > } /* namespace */
> >
> > The above code is from a DLL which gets used by an exe.  The DLL
> compiles and links just fine and the exe compiles.  But when I try to link
> the exe, Clang's linker complains that it can't find '_the_keyboard'
>
> As far as I understand it, if you specify __declspec(dllexport) for a
> whole class, then *all* members, including statics, get explicitly exported
> in the DLL image.
>
> I.e. it is as if you had manually specified __declspec(dllexport) to each
> and every member. I don't know if there is any way to override that for
> just a single class member, for example as with gcc you could add a
> __attribute__((visibility("hidden"))) to one of them.
>
> So maybe you can selectively add DLL_API to those class members that you
> need exported, as described here:
>
> https://docs.microsoft.com/en-us/cpp/cpp/using-dllimport-and-dllexport-in-cpp-classes?view=msvc-160#_pluslang_using_dllimport_and_dllexport_in_c2b2bselectivememberimportexport
>
> -Dimitry
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210922/5238fe87/attachment.html>


More information about the llvm-dev mailing list