static lib drops objects with side-effects
Wesley W. Terpstra
wesley@terpstra.ca
Mon Feb 10 16:03:00 GMT 2003
Good afternoon.
The current cvs binutils ld has a very strange (and broken) behaviour.
main.cpp:
int main() { return 0; }
---
lib.cpp:
#include <iostream>
using namespace std;
static struct Peanut { Peanut() { cout << "This works" << endl; } }
static_nut;
---
Compile these both to main.o and lib.o with g++ (3.2 or 2.95.4).
Now try linking them:
g++ main.o lib.o -o works
This will correctly include the static_nut and print output
g++ -shared lib.o -o libfat.so
g++ -L. -lfat main.o -o works2
This will also include the static_nut and print output
ar qc libfat.a lib.o
g++ main.o libfat.a -o fails
This will NOT include the static_nut and will fail to print output
This is a bug.
A quote from Hal Black who also had this problem:
From the C++ draft spec 2 December 1996:
Section 3.7.1:
2 If an object of static storage duration has initialization or a
destructor with side effects, it shall not be eliminated even if it
appears to be unused, except that a class object or its copy may be
eliminated as specified in 12.8. [hwb: see ** below]
This is talking about the storage of the object, but storage implies
initialization (and destruction).
From the common sense perspective, a simple piece of code like this
shouldn't execute differently based on how you call the linker.
Further considerations include that it breaks the Singleton registry design
pattern outlined in most C++ design books.
Another example of good code which this breaks (from Dr. Dobbs):
http://www.cs.unm.edu/~crowley/cs580/self-registeringobjects.html
Thanks for your time.
--
Wesley W. Terpstra <wesley@terpstra.ca>
More information about the Binutils
mailing list