This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/52069] ARM: initialization of static member in template struct


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52069

--- Comment #8 from Thomas Betker <thomas.betker@rohde-schwarz.com> 2012-02-01 10:51:58 UTC ---
> There's a reason the standard says "no diagnostic required."
> 
> When compiling libtmpl.so, how is the compiler supposed to know that a
> different translation unit which it can't see (and which might not even have
> been written yet) will implicitly instantiate the member?  When compiling
> main.o, how is the compiler supposed to know that an explicit specialization
> exists in a separate translation unit which it can't see?

Okay. So if I read the quote correctly, the standard does not require explicit
specialization, it just requires that an explicit specialization, if present,
is declared before any implicit instantiation. This explains why no there is no
warning if the explicit specialization is missing.

However, this also means that the test case does not violate the quoted rule
because there is simply no explicit specialization at all. I am quite willing
to believe that it is ill-formed, but the reason lies probably in the rules for
implicit specialization; I will have to read up on this.

> With optimisation enabled the compilation of main.o probably removes condition
> because the constant is known to be zero because there has been no explicit
> specialization declared. Without optimisation a weak symbol is emitted, which
> may or may not be replaced by the weak symbol in libtmpl.so that has a
> different value.

objdump says that the symbol S<T>::id both in testbug and in libtmpl.so (with
and without optimization) is a global, strong object in .bss; the symbol
(exists and) is undefined in main.o. 

Without optimization, S<T>::id is initialized in libtmpl.so by
__static_initialization_and_destruction_0(int, int) [which is called by
'<global constructors keyed to S<T>::id']. When run on the target, the function
is relocated to point to the object in testbug (i did a disassembly in gdb). So
in some sense, it S<T>::id in libtmpl.so is indeed treated as a weak object.

With optimization, S<T>::id is initialized in libtmpl.so directly by 'global
constructors keyed to S<T>::id'. When run on the target, the function still
points to the object in libtmpl.so, which no longer seems to be weak. 

I am afraid that this inconsistency still bothers me, apart from the fact that
I couldn't reproduce the problem for x86.

When the explicit specialization is added in tmpl.h, or just in tmpl.cpp, the
symbol S<T>::id both in testbug and in libtmpl.so (with optimization) is a
global, weak object in .bss.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]