[comp.lang.c++] another Zortech bug?

rchen@m.cs.uiuc.edu (02/10/90)

I am posting for a friend who has only "read-only" access
to this news group.

/*-------------------- cut here --------------------------*/ 
 
I'm running Zortech 2.0, and possibly the problem is in the
compiler, but since the details of how to do this don't seem
to be discussed anywhere, I'm not yet ready to point the
finger in Walter's direction.
 
The problem is to do with static members in a class, where
the static member is 1) an array; and 2) a user-defined
class with a single constructor which takes no parameters.
 
So we have a class which is defined along the lines of:
 
class class_with_constructor
 { int dummy1, dummy2, /* ...*/ ;
 
public:
  class_with_constructor(void);
  ~class_with_constructor(void); };
 
and then another one which uses the first, as in:
 
class class_with_problem
{ static class_with_constructor array_name[ARRAY_SIZE];
 
public:
  class_with_problem(void);
  ~class_with_problem(void); };
 
finally, let's specify a global instance of the latter
class:
 
class_with_problem global_variable;
 
Now, what I want to happen is to have the constructors for
each element in the array "array_name" be called before the
call to the constructor to class_with_problem, since the
instantiation "global_variable" calls the latter construc-
tor, which in turn uses information stored in the array
"array_name". This information is intialised in the con-
structor for "class_with_constructor".
 
The 2.0 Ref manual merely says, in section 9.4, that "The
declaration of a static member in its class declaration is
*not* a definition. A definition is required elsewhere".
Fine, but where, and how?? Lippman gives an example for a
class with a static double member, but it isn't obvious to
me how to extrapolate the example to handle arrays; nor is
it obvious when or even if a constructor for a user-defined
type would be called.
 
I spent about three hours mucking
about with various combinations of things yesterday; most of
them compiled, but none of them worked. What actually hap-
pened in every reasonable case was that
class_with_constructor() *was* called ARRAY_SIZE times, but
with a "this" defined incorrectly each time; the first call
was with this == &global_variable; after that the value of
this increased with each call by some amount, probably
sizeof(class_with_constructor), although I didn't check
that.
 
This behavious is obviously designed to crash a program
rapidly...as it did.
 
So, how do I get the constructor called the right number of
times and with the first this == &array_name??
 
Hope this is an easy one for you...
 
All the best
 
  Doc Evans
 
 
SPAN:   ORION::DEVANS
Snail:  Radiophysics, Inc., 5475 Western Ave., Boulder, Colorado 80303 USA
Analogue switching network: (303)-447-9524
 
Non-work-related:
Packet (AX.25): NQ0I @ WA8ZIA
Packet (TCP/IP): nq0i@nq0i.ampr.org [44.20.0.3]

rvadnais@pyramid.pyramid.com (VadGuy) (02/11/90)

In article <4800083@m.cs.uiuc.edu> rchen@m.cs.uiuc.edu writes:

>I'm running Zortech 2.0, and possibly the problem is in the
>compiler, but since the details of how to do this don't seem
>to be discussed anywhere, I'm not yet ready to point the
>finger in Walter's direction.
> 
>The problem is to do with static members in a class, where
>the static member is 1) an array; and 2) a user-defined
>class with a single constructor which takes no parameters.
 
[specific example of problem deleted]

We recently ran into this same problem recently in our C++ class.  Here's
what my professor had to say about it:

   From cstaley Wed Feb  7 11:26:37 1990
   Here are two fun facts I've learned about C++:
   ...
   2.
   Buried deep in the innards of Stroustrup is this little rule that says that
   objects that have a constructor may not be used as static data members of a
   class.  This means that you may not have the associative_array as a static
   member of Id, even though this would be stylistically correct.  I can think
   of no reason for this dumb rule, but I didn't design the language. 

I got around this limitation by declaring a null pointer to the
associative_array and then calling the constructor explicitly in 
the constructor for Id when the pointer has a null value.  This requires
the overhead of a check everytime the constructor for Id is called, but 
it does the trick.

In other words: it's not a bug, it's a feature. :)

Hope this helps.
---
Bob Vadnais                              rvadnais@polyslo.CalPoly.EDU
"Have a nice day!"               (Offer void where prohibited by law)

jeffa@hpmwtd.HP.COM (Jeff Aguilera) (02/13/90)

>  ...
>  2.
>  Buried deep in the innards of Stroustrup is this little rule that says that
>  objects that have a constructor may not be used as static data members of a
>  class.  This means that you may not have the associative_array as a static
>  member of Id, even though this would be stylistically correct.  I can think
>  of no reason for this dumb rule, but I didn't design the language. 

This is wrong.  The rule is in section 9.4 of the Reference Manual:

    "Static members of a class declared local to some FUNCTION have
    no linkage and cannot have static members that require initialization
    (except for the default "all zeros" initialization (Section 8.4))."

Static members with constructors are permitted within a CLASS.  The
declaration should be given within the .h file, and the initialization in
the .c file.  Example:

//X.h
class X {
    static Y y;
};

//X.c
Y X::y = ...; 

Unfortunately, Zortech 2.0 botches some static member initializations,
especially when the static member is an array.   Perhaps Walter can list
the case known not to work.  

I had an example under 2.0 that resulted in multiple invokations of the
constructor and destructor for a static member.  The problem disappeared 
with 2.06.  (The original example did not involve virtual inheritance.  
This case is still broken.)
----
jeffa