This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
static lib drops objects with side-effects
- From: "Wesley W. Terpstra" <wesley at terpstra dot ca>
- To: binutils at sources dot redhat dot com
- Date: Mon, 10 Feb 2003 17:03:04 +0100
- Subject: static lib drops objects with side-effects
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>