From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7195 invoked by alias); 10 Sep 2004 06:43:53 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 7080 invoked from network); 10 Sep 2004 06:43:50 -0000 Received: from unknown (HELO baldur.globalsymmetry.com) (66.92.149.152) by sourceware.org with SMTP; 10 Sep 2004 06:43:50 -0000 Received: from ljosalfr.globalsymmetry.com (ljosalfr.globalsymmetry.com [192.168.0.27]) by baldur.globalsymmetry.com (8.12.3/8.12.3/SuSE Linux 0.6) with ESMTP id i8A6j8Em005488 for ; Fri, 10 Sep 2004 02:45:09 -0400 Received: from ljosalfr.globalsymmetry.com (localhost [127.0.0.1]) by ljosalfr.globalsymmetry.com (8.12.10/8.12.10/SuSE Linux 0.7) with ESMTP id i8A6hKSk030213 for ; Fri, 10 Sep 2004 02:43:20 -0400 Received: from localhost (localhost [[UNIX: localhost]]) by ljosalfr.globalsymmetry.com (8.12.10/8.12.10/Submit) id i8A6hK0d030212 for gcc@gcc.gnu.org; Fri, 10 Sep 2004 02:43:20 -0400 X-Authentication-Warning: ljosalfr.globalsymmetry.com: hattons set sender to hattons@globalsymmetry.com using -f From: "Steven T. Hatton" Organization: Global Symmetry To: gcc@gcc.gnu.org Subject: Fwd: Linking public: static const members in lib*.a's User-Agent: KMail/1.7 MIME-Version: 1.0 Content-Disposition: inline Date: Fri, 10 Sep 2004 07:29:00 -0000 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-Id: <200409100243.19933.hattons@globalsymmetry.com> X-SW-Source: 2004-09/txt/msg00583.txt.bz2 I've posted the following to a few different newsgroups and mailing lists. The best explanation I've seen so far is that I'm asking the linker to evaluate the static initialization in an external library, and it doesn't know how to do that. I believe the code is valid C++, and I believe I am using the language as it was intended to be used. What exactly is the problem with what I'm trying to do in the following? Sorry about the big code dump. I tried to get it down to the minimum required to demonstrate the problem. On the following I run aclocal autoheader autoconf automake -a -c --gnits ./configure make with the results shown at the end of the code listing. The problem seems to be related to my using static const class members. Other similarly configured programs work OK. Can someone tell me what I'm doing wrong here? ./configure.ac # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) AC_INIT(testlibs, 0.1, hattons@here.com) AC_CONFIG_SRCDIR([main.cpp]) AC_CONFIG_HEADER([config.h]) AM_INIT_AUTOMAKE # Checks for programs. AC_PROG_CXX AC_PROG_CC # Checks for libraries. AC_PROG_RANLIB # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE # Checks for library functions. AC_CONFIG_FILES([Makefile sth/Makefile sth/util/Makefile]) AC_OUTPUT ./Makefile.am INCLUDES = -I$(top_srcdir)/sth $(all_includes) bin_PROGRAMS = testlibs testlibs_SOURCES = main.cpp testlibs_LDFLAGS = $(all_libraries) testlibs_LDADD = $(top_builddir)/sth/libsth.a SUBDIRS = sth ./main.cpp #include "ColorTest.h" #include int main(int argc, char* argv[]) { using sth::ColorTest; ColorTest* ct = new ColorTest(std::cout); } ./sth/Makefile.am INCLUDES = -I$(top_srcdir)/sth/util $(all_includes) SUBDIRS = util lib_LIBRARIES = libsth.a libsth_a_LIBADD = $(top_builddir)/sth/util/libutil.a noinst_HEADERS = ColorTest.h libsth_a_SOURCES = ColorTest.cpp ./sth/ColorTest.h #ifndef STHCOLORTEST_H #define STHCOLORTEST_H #include namespace sth { class ColorTest { public: ColorTest(std::ostream& out); ~ColorTest(); }; }; #endif ./sth/ColorTest.cpp #include "ColorTest.h" #include int main(int argc, char* argv[]) { using sth::ColorTest; ColorTest* ct = new ColorTest(std::cout); } ./sth/util/Makefile.am INCLUDES = -I$(all_includes) lib_LIBRARIES = libutil.a noinst_HEADERS = RgbColor.h Printable_IF.h libutil_a_SOURCES = RgbColor.cpp ./sth/util/RgbColor.h #ifndef UTILRGBCOLOR_H #define UTILRGBCOLOR_H #include "Printable_IF.h" namespace sth { namespace util { /** @author Steven T. Hatton */ class RgbColor : public Printable_IF { public: RgbColor(const unsigned char& r=255, const unsigned char& g=127, const unsigned char& b=127); unsigned char R() const; void R(const unsigned char& r); unsigned char G() const; void G(const unsigned char& g); unsigned char B() const; void B(const unsigned char& b); std::ostream& print(std::ostream& out) const; static const RgbColor RED; static const RgbColor GREEN; static const RgbColor BLUE; static const RgbColor BLACK; static const RgbColor WHITE; static const RgbColor MAGENTA; static const RgbColor CYAN; static const RgbColor YELLOW; private: unsigned char m_r; unsigned char m_g; unsigned char m_b; }; inline unsigned char RgbColor::R() const { return m_r; } inline void RgbColor::R(const unsigned char& r) { m_r = r; } inline unsigned char RgbColor::G() const { return m_g; } inline void RgbColor::G(const unsigned char& g) { m_g = g; } inline unsigned char RgbColor::B() const { return m_b; } inline void RgbColor::B(const unsigned char& b) { m_b = b; } } } #endif ./sth/util/RgbColor.h #include "RgbColor.h" namespace sth { util::RgbColor::RgbColor(const unsigned char& r, const unsigned char& g, const unsigned char& b) : m_r(r) , m_g(g) , m_b(b) {} const util::RgbColor util::RgbColor::RED = util::RgbColor(255,0,0); const util::RgbColor util::RgbColor::GREEN = util::RgbColor(0,255,0); const util::RgbColor util::RgbColor::BLUE = util::RgbColor(0,0,255); const util::RgbColor util::RgbColor::BLACK = util::RgbColor(0,0,0); const util::RgbColor util::RgbColor::WHITE = util::RgbColor(255,255,255); const util::RgbColor util::RgbColor::MAGENTA = util::RgbColor(255,0,255); const util::RgbColor util::RgbColor::CYAN = util::RgbColor(0,255,255); const util::RgbColor util::RgbColor::YELLOW = util::RgbColor(255,255,0); /*! \fn util::RgbColor::print(std::ostream& out) const */ std::ostream& util::RgbColor::print(std::ostream& out) const { out << "util::RgbColor::{r=" << this->m_r << ",g=" << this->m_g << ",b=" << this->m_b << "}\n"; return out; } } ./sth/util/Printable_IF.h #ifndef PRINTABLE_IF_H #define PRINTABLE_IF_H #include namespace sth { namespace util { class Printable_IF { public: Printable_IF() {} virtual ~Printable_IF() {} virtual std::ostream& print(std::ostream& out) const = 0; }; inline std::ostream& operator<<(std::ostream& out, const Printable_IF& pif) { return pif.print(out); } } } #endif undefined reference to `sth::util::RgbColor::RED' ./sth/libsth.a(ColorTest.o)(.text+0x6f):./sth/ColorTest.cpp:9: undefined reference to `sth::util::RgbColor::RED' ./sth/libsth.a(ColorTest.o)(.text+0x77):./sth/ColorTest.cpp:9: undefined reference to `sth::util::RgbColor::RED' ./sth/libsth.a(ColorTest.o)(.text+0x81):./sth/ColorTest.cpp:9: undefined reference to `vtable for sth::util::RgbColor' ./sth/libsth.a(ColorTest.o)(.text+0x8f): In function `sth::ColorTest::ColorTest[in-charge](std::basic_ostream >&)': -- Regards, Steven