From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26803 invoked by alias); 4 Aug 2015 17:06:35 -0000 Mailing-List: contact gcc-help-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-help-owner@gcc.gnu.org Received: (qmail 26790 invoked by uid 89); 4 Aug 2015 17:06:35 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-qk0-f177.google.com Received: from mail-qk0-f177.google.com (HELO mail-qk0-f177.google.com) (209.85.220.177) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Tue, 04 Aug 2015 17:06:34 +0000 Received: by qkdv3 with SMTP id v3so5581918qkd.3 for ; Tue, 04 Aug 2015 10:06:31 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.55.21.205 with SMTP id 74mr8349590qkv.19.1438707991735; Tue, 04 Aug 2015 10:06:31 -0700 (PDT) Received: by 10.140.95.3 with HTTP; Tue, 4 Aug 2015 10:06:31 -0700 (PDT) In-Reply-To: References: <63FDE6C4-EFC2-44DD-991E-0BE895586162@gmail.com> Date: Tue, 04 Aug 2015 17:06:00 -0000 Message-ID: Subject: Re: Explicit instantiation and static objects in different modules From: Jonathan Wakely To: Alexander Monakov Cc: Nikolay Vorobyov , gcc-help Content-Type: text/plain; charset=UTF-8 X-IsSubscribed: yes X-SW-Source: 2015-08/txt/msg00022.txt.bz2 On 4 August 2015 at 17:52, Alexander Monakov wrote: > On Tue, 4 Aug 2015, Jonathan Wakely wrote: > >> On 4 August 2015 at 16:00, Nikolay Vorobyov wrote: >> > Is this a gcc's bug? >> >> I believe this is due to how symbol resolution works in DLLs on >> Windows, where each DLL has its own copy of the static variable. I >> don't know how to make it work as required by the C++ standard. > > One way would be to eliminate the inline definition of getInstance() in the > header file, and move it into inst.cpp. > > If you inspect generated files with 'nm -C', you'll see that both libinst.dll > and liba.dll have a definition for StaticObject::getInstance()::t. > > Jonathan, I think there might be a GCC bug here, but not what Nikolay > originally meant. With -std=c++11, 'extern template' should prevent the > compiler from instantiating methods of StaticObject, but it doesn't happen. > Here's a minimal example: > > template > struct S { > static int bar() > { > return V; > } > }; > > extern template struct S<42>; > > int foo() > { > return S<42>::bar(); > } > > Compile with g++ -std=c++11 -S -o- -Os and observe that 'foo' is optimized to > 'return 42', although 'bar' should not have been instantiated. If you don't > have a template class and make 'bar' itself a template function, GCC does not > optimize 'foo', as expected. WDYT? The extern template tells the compiler it doesn't *need* to instantiate the template, because it will be explicitly instantiated in another translation unit. But that doesn't mean it *must not* instantiate it. The compiler can choose to inline the function and in that case it will implicitly instantiate it. That should be unobservable because the One Definition Rule means that the implicitly instantiated definition that gets inlined and the explicitly instantiation definition in the other translation unit must be identical. The Windows linkage model seems to break that assumption ... so I don't know what the right behaviour is.