[Err, I pressed Enter too early, here follows the description. Sorry.] Consider this piece of code: template <typename T> struct managed { bool (*_gc_fun) (void*); // A hook for garbage collection T data; managed (const T& t) : _gc_fun (no_gc), data(t) { } ~managed () { } // How can we force GCC-3.4 to emit code for this one when a constructor // is present? Moving it out of the class definition doesn't help. static bool no_gc (void*) { return false; } }; int main() { managed<int>* ht = new managed<int>( 42 ); delete ht; } Using the current mainline, i.e. 3.4 20030628 (experimental) one gets "undefined reference to `managed<int>::no_gc(void*)'" at link-time. GCC-3.3 and earlier all used to produce a weak symbol resulting in a working program. The above piece of code was extracted while trying to port the CLN library <http://www.ginac.de/CLN/> to the current mainline.
Wooops, I just discovered that changing the ctor like this makes it work: template <typename T> struct managed { bool (*_gc_fun) (void*); // A hook for garbage collection T data; managed (const T& t) : _gc_fun (managed<T>::no_gc), data(t) { } // <=== ~managed() { } static bool no_gc (void*) { return false; } }; Is this really correct behaviour? I don't think so. It does not seem to be one of the usual two-stage lookup problems since there is nothing ambiguous about the static function no_gc(void*). But maybe I'm wrong... If it is correct, please feel free to change this bug's resolution to INVALID.
Confirmed. A 3.4 regression. I think it's a duplicate of some other report, though. The workaround is nice, but shouldn't be necessary. W.
This is a duplicate of 10804 *** This bug has been marked as a duplicate of 10804 ***
Also, if the problem had been name-lookup, it would have resulted in a compile error, not a link error. So, it's not a problem with the name-lookup.