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


Thanks for replying, Ian.

Ian Lance Taylor wrote:

Hal Black <black at ieee dot org> writes:


What I'm saying is not to use all the symbols, but to include all
static initializers as "symbols that are being looked for".  Even if
they aren't explicitly referenced by annother piece of code, they are
implicitly referenced by virtue of being static initializers.


That would mean that every static initializer in a .a file would be
brought in

Yes, as desired.


> which would doubtless bring in other object files as well.

If the static initializer calls other functions, then those would be required as well, just as normal ld behavior.

It means that including any class with a static initializer in a .a
file would mean that that class would be included in all programs
linked with that .a file.

Yes. That's the desired behavior. If a developer were to develop a library with a static initializer with side-effects, it would be something that should be called whenever that library was used.


Other classes with no static initializers would only be used as needed, as they are now.

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?

> This would go against the very idea of a .a
file, which is that only required objects are included.

My claim is that if it has a static initializer, it is required. If it is called from any included object, it is required (as it works now). Therefore this doesn't break the idea the only required objects are included.


-----
Also, just to clarify since it got lost in the quoting, I'm talking about this scenario:


class A {
public:
    A() { printf("Hello world!\n"); }
};
A a;

I claim if this code is put in a library, printf should be called. Because "a" has static storage duration and has side effects, its initializer cannot be eliminated per 3.7.1.2 of the draft standard.

So, when I say static initializer in the context of this discussion, the above code fragment is what I mean.

I would say that not looking for static initializers constitutes
eliminating them...

No, because they were never included in the first place.

The claim is that never including them in the first place is elimination.


It's reasonably easy to avoid this problem: put the static initializer
in the same source file as a class virtual function.  Since the
class virtual function must be included, the initializer will be
brought in as well.

The claim is that static initializers as specified above are in this same category of things that must be included.


If you don't have any virtual functions, then you do need to take some
other action to force that object file to be included, such as using
global variables in some way.

Or maybe .a files are simply the wrong tool for the job.  Maybe you
should use ld -r to form several .o files into one large .o file.
Linking against that will ensure that everything is brought in.

Thanks for large .o idea. This, and other workarounds such as the one provided by Alexandre, would work great for my immediate purposes.


However, I'm not having a problem finding a workaround, I'm addressing the point of how static initializers should behave in a library. The workarounds proposed, though they work great as a fix for what I was having problems with, don't provide library functionality (only include what's needed). Also, they require extra steps to use common implementations of automatic registration patterns in a library.


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