sanders@boulder.Colorado.EDU (Bruce Sanders) (06/11/87)
When I compile and run the following C++ program, I get a segmentation fault.
C++ version <<cfront 1.2.1 2/16/87>>
Sun OS version 3.3
// ----------------------------------------------------------------------------
#include <stream.h>
class c {
char *s;
public:
c(char *string) { s = string; cerr << "constructor "; print(); }
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
void print() { cerr << s << "\n"; }
};
c global("global");
main()
{
c local("local");
c stat("static");
global.print();
local.print();
stat.print();
}
// ----------------------------------------------------------------------------
adb gives the following output:
% adb a.out
core file = core -- program ``a.out''
SIGSEGV 11: segmentation violation
$c
__ostream__lshiftFPC__(0x20d60,0x20071) + 30
__STIjnk_c_() + 24
__main() + 14
_main(0x1,0xefffbbc,0xefffbc4) + e
If I comment out the two lines with "global" in them, everything works,
producing the following output:
% a.out
constructor local
constructor static
local
static
Alternatively, if I remove the cerr and print statements (indicated in
the comment) from the constructor, it works correctly, producing
% a.out
global
local
static
Is this a bug, or am I doing something illegal?
thanks
bruce
Bruce W. Sanders
Department of Computer Science
University of Colorado
Campus Box 430
Boulder, CO 80309-0430
(303) 492-8118
sanders@bouldermoore@ucbcad.berkeley.edu (Peter X Moore) (06/11/87)
This is not so much a bug, as an unavoidable feature of the way global constructors are implemented. Both your object and cerr have global constructors. All global constructors are grouped together and called IN ESSENTIALLY A RANDOM ORDER before main. You are having the good fortune of having your object's constructor called before cerr's constructor is called, and so the code for << is core dumping as it tries to use an unintialized data structure. The immediate patch is to either use a local stream variable instead of cerr or fall back to fprintf. To fix the general problem seems VERY tough, since it seemingly requires global interdependacy analysis between all constructors. Other languages must face this problem, does anyone know what they do (or don't do)? Peter Moore moore@Berkeley.edu ...!ucbvax!moore
jon@oddhack.caltech.edu (Jon Leech) (06/11/87)
Summary: Expires: Sender: Followup-To: Distribution: In article <731@boulder.Colorado.EDU> sanders@boulder.Colorado.EDU (Bruce Sanders) writes: >... >If I comment out the two lines with "global" in them, everything works, >producing the following output: >... >Alternatively, if I remove the cerr and print statements (indicated in >the comment) from the constructor, it works correctly, producing >... >Is this a bug, or am I doing something illegal? The constructor for 'global' is probably being called before the constructor for 'cerr'. Since cerr is declared in a different file, it appears (see the reference manual 8.6.2) that you have no control over the order in which these contructors are called, and thus should not write code with this sort of dependency. -- Jon Leech (jon@csvax.caltech.edu || ...seismo!cit-vax!jon) Caltech Computer Science Graphics Group __@/ ``There is only one spacefaring nation today. And it's not the United States, comrade!''
ark@alice.UUCP (06/12/87)
In article <731@boulder.Colorado.EDU>, sanders@boulder.UUCP writes:
->
-> When I compile and run the following C++ program, I get a segmentation fault.
-> C++ version <<cfront 1.2.1 2/16/87>>
-> Sun OS version 3.3
->
-> // ----------------------------------------------------------------------------
-> #include <stream.h>
->
-> class c {
-> char *s;
-> public:
-> c(char *string) { s = string; cerr << "constructor "; print(); }
-> // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-> void print() { cerr << s << "\n"; }
-> };
->
-> c global("global");
->
-> main()
-> {
-> c local("local");
-> c stat("static");
-> global.print();
-> local.print();
-> stat.print();
-> }
It looks like what is happening is that the constructor for the variable
"global" is trying to print stuff before the I/O library is initialized.
This is not a bug. The stream library relies on static constructors
for its initialization, and there is no guarantee that static
constructors will be executed in any particular sequence.nadkarni@ashok.dec.com (04/13/90)
Am I doing something wrong or is this a bug in the compiler ? It appears
as though the compiler tries to optimize by not copying the virtual table
function pointer when assigning an object to another. Unfortunately,
in this case it does not work. The compiler is Zortech C++ 2.06.
I expected to see the output
C
A
B
and instead saw
A
A
A
Could someone please confirm this is a bug (in my code or the compiler).
---------------------- code follows ------------------
#include <stream.hpp>
class C {
public:
virtual void output() {cout << "C\n";}
};
class A : public C {
public:
virtual void output() {cout << "A\n";}
};
class B : public C {
public:
virtual void output() {cout << "B\n";}
};
union AB {
class B b;
class C c;
class A a;
};
main ()
{
A a;
B b;
C c;
AB ab;
ab.c = c;
ab.c.output();
ab.a = a;
ab.a.output();
ab.b = b;
ab.b.output();
}
Thanks,
/Ashok Nadkarni
Digital Equipment Corp.williamt@athena1.Sun.COM (William A. Turnbow) (04/14/90)
In article <10259@shlump.nac.dec.com> nadkarni@ashok.dec.com writes: > >Am I doing something wrong or is this a bug in the compiler ? It appears >as though the compiler tries to optimize by not copying the virtual table >function pointer when assigning an object to another. Unfortunately, >in this case it does not work. The compiler is Zortech C++ 2.06. >I expected to see the output ------ Your program doesn't even compile on our compiler (AT&T 2.0.02). It yields the following: "tst8h.C", line 18: error: member AB::b of class B with constructor in union "tst8h.C", line 18: error: member AB::c of class C with constructor in union "tst8h.C", line 18: error: member AB::a of class A with constructor in union 3 errors Just a guess, but there is a virtual field that gets auto initialized when you declare an instance of the class. By trying to do a union, there would be three different constructors to call for the same memory location, resulting in indeterminate behavior. But this is just a guess. -wat- *** We felt the effects of herb were so dangerous that it was better to lie to the american public to save them rather than tell them the truth -- Partnership for a Drug Free America
berryc@arcturus.uucp (Craig D. Berry (x1710)) (03/26/91)
I have a class with a static member function:
class foo
{ ...
public:
static foo barfunc(); // Returns value of a foo object.
...
}
Now, somewhere else, I try to use barfunc to initialize a foo:
foo quux = foo::barfunc();
This doesn't work; the compiler wants a ( after foo::, for reasons
entirely mysterious to me. Could be expecting one of foo's constructors,
I suppose...
However,
foo quux = (foo::barfunc());
works as intended; quux is created with the value returned by barfunc.
Am I missing something, or is my compiler (Turbo C++ 1.0) broken?steve@taumet.com (Stephen Clamage) (03/29/91)
berryc@arcturus.uucp (Craig D. Berry (x1710)) writes: |I have a class with a static member function: | class foo { public: static foo barfunc(); } |Now, somewhere else, I try to use barfunc to initialize a foo: | foo quux = foo::barfunc(); |This doesn't work... |Am I missing something, or is my compiler (Turbo C++ 1.0) broken? This is a compiler bug. I have the latest release, and the example works. -- Steve Clamage, TauMetric Corp, steve@taumet.com