This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils 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]

Re: [BUG] ld behavior varies for C++ static initializer dependingon .a or .o input


Alexandre Oliva wrote:

On Apr 12, 2003, Hal Black <black at ieee dot 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.


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