[BUG] ld behavior varies for C++ static initializer depending on .a or .o input

Hal Black black@ieee.org
Sun Apr 13 02:11:00 GMT 2003


Alexandre Oliva wrote:

> On Apr 12, 2003, Hal Black <black@ieee.org> wrote:
> 
> 
>>>That would mean that every static initializer in a .a file would be
>>>brought in
> 
> 
>>Yes, as desired.
> 
> 
> Maybe in your specific application.  But think of the Standard C++
> library.  It may contain hundreds, if not thousands, of global
> initializers, that are of no use for most programs that don't happen
> to use the particular feature that depend on some of these
> initializers.

I'm not an expert on g++ symbols, but I'm assuming the static intializer 
of the sort I'm talking about is is named 
__static_initialization_and_detruction.* because that's what nm reports 
for my test program.

When I run nm on libstdc++*.a and grep for static_initialization, I get 
not thousands, not hundreds, but zero matches.  So, if I'm right about 
the naming, the program would get no bigger if the changes I suggested 
were implemented.

OTOH, I could be totally wrong.  8')  I really know nothing about the 
details of how g++ does naming of C++ constructs.

[caveat: I don't have access to the latest stuff right now, this is with 
mandrake 9.0 - maybe they have added thousands of static initializers 
since then]

I counted 18 static initializers total in /usr/lib.  I don't know 
whether these are meant to be called every time the library is linked 
against, or just when a certain feature is used.

 > Bringing them in just because you would like it to be
> so is not exactly a reasonable proposition.

It's not a question of me liking it to be so.  I have already stated 
that I am fine with the work around.  I am raising the point how the C++ 
spec is interpreted in terms of libraries for discussion.  The way to 
dispute this point is to argue against the point, not wave it off 
because you infer endearment of an individual to it, which is irrelevant 
on whether it is the right way to do it or not.

I just hadn't heard any valid reasons against having it be as I 
describe, and it seems like the correct interpretation of the spec.

>>If you don't think this is the proper usage, what is your
>>interpretation of the meaning of having a static intializer (or items
>>with static storage duration in general) in a library?
> 
> 
> No different from having it in an object file: if the object file is
> linked in, the static initializer is run.  The difference is that
> object files listed in the command line are always linked in, whereas
> those in a static library get linked in only if they would resolve
> some symbol the linker is looking for.

I understand the behavior of the tools.  What I asked was what is the 
meaning of having objects with static storage in a library.

Based on an earlier portion of your reply, I am taking your 
interpretation to mean that a static initializer in a library is only 
called when something references an instance of its class or members, 
but not otherwise.  I don't believe this is a valid view from reading 
the C++ spec.

>>My claim is that if it has a static initializer, it is required.
> 
> 
> If we implemented this mis-feature, you'll come back tomorrow and
> complain about the bloat from all these modules being linked in that
> are not needed for your program to run, and the answer will be that
> they do contain static initializers so, per your request, they have to
> be brought in.

If they were not needed for the program to run, the behavior (not 
counting performance/memory footprint for the moment) would be the same 
whether they were included or not.  Desired side-effects of the static 
initializers don't happen when they're not included, therefore they are 
required for the program to run.

I see your point that if the custom is to put in instances of static 
storage whose initializers aren't meant to be called all the time, some 
uneccesary bloat could result.  If they are supposed to be called, 
however, they aren't unneccesary.

I don't know whether the 18 static initializers in my /usr/lib are meant 
to be used the way I describe or the way you describe, so I can't say 
whether these are unneccesary or neccesary.

Regardless, if my interpretation of the C++ spec is correct, it is a 
flaw in the library to create static storage items with initializers 
with side effects that aren't meant to be run for all users of the 
library.  In that case, the linker would be following the spec and would 
deserve no complaints.  It's not the auto-maker's fault if the car is 
working fine and you get caught speeding.

But, if you don't want to implement it to avoid complaints, it's your 
project, not mine, so I can't argue with that.



More information about the Binutils mailing list