🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: alt.os.linux.mandrake
Article #495

Re: the phrases "undefined reference" and "in-charge"

#495
From: Guy Harrison
Date: Fri, 31 Oct 2003 05:46
158 lines
6586 bytes
Novice wrote:

> I'm attempting to compile, link and then execute some C++ code I've
> written - I've executed it in the past, but recently made some changes to
> it on one platform and then ported it BACK over to Mandrake (i.e. I have
> compiled, linked and executed the code previously on the same Mandrake
> computer that I'm trying to do now) and attempted to re-compile and link
> on
> the same Mandrake computer I had it running on before.  Unfortunately, I
> can't get ride of the following linker errors:
> 
> TimSystem.o(.text+0x1bf): In function
> `__static_initialization_and_destruction_0(int, int)':
> : undefined reference to
> `txl::io::BufferedOutputStream::BufferedOutputStream[in-charge]()'
> collect2: ld returned 1 exit status
> 
> I've done some google'ing on the phrases:
> "undefined reference" and "in-charge"

The "undefined reference" is what it appears - the linker can't locate the
symbol it emits.

Read "in-charge" as "ctor" and "not-in-charge" as "dtor".

That lengthy "static_init..." (or very similar depending on gcc version) is
used internally by gcc to handle construction and destruction of objects
which your code has declared static. These are the ones that have their
ctor invoked prior to entering main() and their dtor invoked after leaving
it. In other words, those pesky uncatchables.

The error can than be read as...

TimSystem defines a static object for which the txl::io:
BufferedOutputStream default ctor has been declared but for which no such
definition can be found.

The .text+0x1bf tells you exactly where to locate the problem should you
desire to wade into the object code.

> In most cases, it appears the user wasn't:
> 1. using g++ or
> 2. using the proper form for includes or
> 3. not using namespaces properly

Or, as a realised on second reading, 'cos you overwrote the file. ;-)

[snip]
 
> using namespace txl::io;
> 
> SmtPrintStreamPtr System::out = SmtPrintStreamPtr (new
> PrintStream(SmtBufferedOutputStreamPtr (new
> txl::io::BufferedOutputStream()), true));
^^^
Unless you've any more static objects not posted then this is it. It could
do with losing its txl::io:: prefix as your 'using' that by this point
anyway (?is it txl::io or txl::io::txl::io?). It ought not be a showstopper
though, just vagueness for the compiler to sort out.

You'll need a handler for the above unless you can guarantee no exceptions
will occur (easier to use auto_ptr).

[snip]

> Here is the definition of the default constructor from
> txl::io::BufferedOutputStream
> -----------------------------------------
>             txl::io::BufferedOutputStream::BufferedOutputStream (){
>             }

There is an occasional problem with gcc which is what originally prompted my
reply.

namespace txl   {
        namespace io    {
                BufferedOutputStream::BufferedOutputStream() {
                }
        }
}

I've always used the more verbose latter form so it's never bitten me which
means someone else will have to fill in the details. Unlikely an issue -
see below.

> -----------------------------------------
> 
> Here is the way I'm compiling:
> -----------------------------------------
> g++ -DVERIFY -DNO_VERISOFT -c *.cpp
> -----------------------------------------

It'll work.
 
> No errors from the compilation.  Then here is the way I'm linking:
> -----------------------------------------
> g++ -DVERIFY -DNO_VERISOFT -o *.o
> -----------------------------------------

I assumed that was a typo. Bugger! It wasn't was it? You've specified the
executable name to be the first object filename that the shell returns for
*.o and now that I do the above I get exactly the same error.

> I've also attempted ordering all of the .o files explicitly (i.e. not
> using *.o) with no better results.
> 
> Any suggestions?

Automate it. Here's a get-you-started (GNU make) 'makefile'. Preserve the
tabs.

CPPFLAGS        ?=-DVERIFY -DNO_VERISOFT
CXXFLAGS        ?=-ansi -pedantic -W -Wall -Werror -g -O0
LDFLAGS         ?=

NAM             =c
ITM             =foo bar
OBJ             =$(ITM:%=%.o)
DEP             =$(ITM:%=%.d)
EXE             =$(NAM)

%.o : %.cpp
                $(CXX) -MMD -c -o $@ $(CPPFLAGS) $(CXXFLAGS) $<

.PHONY:         all clean allclean

all:            $(EXE)

clean:
                rm -f $(OBJ)

allclean:       clean
                rm -f $(DEP) $(EXE)

$(EXE): $(OBJ)
                $(CXX) -o $(EXE) $(OBJ) $(LDFLAGS)

-include        $(DEP)

It's the minimal I can dream up which will generate header dependancies for
you (the *.d files that appear). Refer to gmake/g++/gcc manuals. You may at
least have to tweek CXXFLAGS (lookup what ?= does btw), sometimes -pedantic
barfs inside system headers.

Plonk your executable name into NAM in place of 'c' and all your sourcefile
names (minus their extenders) into ITM in place of 'foo' and 'bar'.

It's just one of a zillion ways to do such a thing. Consider it a generic
template useful for quickly building source - ordinarily you'd write a
customised one (or use autotools).

Note I've cut it down to the extent it won't handle anything but C++ *.cpp
files "correctly" and it's easy to break dependancy generation by fiddling
with the build rule (hint: duplicate it rather than adding %.cc %.C to it).


-- 
Guy Harrison
Technical Details
Message-ID: <49a971-7i42.ln1@sd.swampdog>
Path: arc1-ca.pugleaf.net!archiver1.google.com!news2.google.com!fu-berlin.de!newsfeed01.sul.t-online.de!t-online.de!newspeer1-gui.server.ntli.net!ntli.net!newsfep4-glfd.server.ntli.net.POSTED!53ab2750!not-for-mail
References: <bnrjs1$mmt$1@knot.queensu.ca>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 10ba33,c3065f741ba0d469
X-Google-Attributes: gid10ba33,public
X-Google-Thread: f8a83,c3065f741ba0d469
X-Google-Attributes: gidf8a83,public
X-Google-ArrivalTime: 2003-10-30 22:00:16 PST
Path: arc1-ca.pugleaf.net!archiver1.google.com!news2.google.com!fu-berlin.de!newsfeed01.sul.t-online.de!t-online.de!newspeer1-gui.server.ntli.net!ntli.net!newsfep4-glfd.server.ntli.net.POSTED!53ab2750!not-for-mail
Message-ID: <49a971-7i42.ln1@sd.swampdog>
From: Guy Harrison <swamp-DEL-dog@ntlworld.com>
Subject: Re: the phrases "undefined reference" and "in-charge"
Newsgroups: alt.os.linux.mandrake,gnu.g++.help
Followup-To: alt.os.linux.mandrake
References: <bnrjs1$mmt$1@knot.queensu.ca>
Lines: 158
User-Agent: KNode/0.7.2
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7Bit
Date: Fri, 31 Oct 2003 05:46:49 +0000
NNTP-Posting-Host: 80.4.128.22
X-Complaints-To: abuse@ntlworld.com
X-Trace: newsfep4-glfd.server.ntli.net 1067580011 80.4.128.22 (Fri, 31 Oct 2003 06:00:11 GMT)
NNTP-Posting-Date: Fri, 31 Oct 2003 06:00:11 GMT
Organization: ntlworld News Service