From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17714 invoked by alias); 9 Apr 2013 12:26:46 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 17693 invoked by uid 48); 9 Apr 2013 12:26:44 -0000 From: "geoff at telesiscomputing dot com.au" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/56892] New: dllexport prevents inline inside dll Date: Tue, 09 Apr 2013 12:26:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: geoff at telesiscomputing dot com.au X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Changed-Fields: Message-ID: X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" MIME-Version: 1.0 X-SW-Source: 2013-04/txt/msg00736.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56892 Bug #: 56892 Summary: dllexport prevents inline inside dll Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned@gcc.gnu.org ReportedBy: geoff@telesiscomputing.com.au Created attachment 29840 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=29840 Preprocessed result of: mingw32-g++.exe -v -save-temps -std=c++11 -O2 -Winline testlib.cpp When the dllexport attribute is used at the class level (which is most common), any inline methods for that class will NOT be inlined inside the shared library binary itself. This prevents the shared library from being fully optimised, sometimes with significant impact on performance. Produced on mingw / gcc v4.7.2, and on mingw64 / gcc v4.8.0. Given these three classes (testlib.hpp): class __declspec(dllexport) A { public: int fa() { return m; } int ga(); private: int m{0}; }; class __declspec(dllexport) B { public: int fb(); int gb(); private: int m{0}; }; inline int B::fb() { return m; } class C { public: int fc() { return m; } __declspec(dllexport) int gc(); private: int m{0}; }; Implemented as (testlib.cpp): #include "testlib.hpp" int A::ga() { return (fa() + 1); } int B::gb() { return (fb() + 1); } int C::gc() { return (fc() + 1); } And then compiled with: -std::c++11 -O2 -Winline testlib.cpp (The -std::c++11 is just for the in-class initializer.) A::fa() is not inlined, and no warning is given. B::fb() is not inlined, the compiler warns that it won't inline. C::fc() is inlined as expected. Almost no-one writes their classes like class C, they use class A or (less commonly) class B. If they use class A style code they won't even know that their inlines are being ignored when building the library itself. I do understand the potential issues (the theory being that exported functions are supposed to replaceable), but if __declspec(dllexport) - a synonym for __attrribute__((dllexport)) - is supposed to emulate the behaviour seen by the same declaration under msvc (why else create the synonym?) then it is failing to do so. See this link for details: http://msdn.microsoft.com/en-us/library/xa0d9ste.aspx It is apparent that dllexport and dllimport are introducing additional semantics above that of "export symbol" and "import symbol". So the other work-around is to stop using dllexport and dllimport and use manual .def files, or --export-all-symbols when calling the linker. Obviously neither options is ideal. It's possible that there could be overlap with this bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50779