Topic: Derived static initializer


Author: David R Tribble <david.tribble@noSPAM.central.beasys.com>
Date: 1998/07/15
Raw View
I, David R Tribble, dtribble@technologist.com, wrote:
>> Given the following code, is the definition of Der:val legal?:
>>     class Base
>>     {
>>     public:
>>         static int  val;
>>     };
>>
>>     class Der: public Base
>>     {
>>         ...
>>     };
>>
>>     /*static*/ int  Der::val = 2;   // Not Base::val

AllanW@my-dejanews.com wrote:
> You are required to define Base::val somewhere.
> This is illegal because val wasn't defined in Der.

I agree, and this *ought* to be true, but I wasn't sure.

Me:
>> Is the definition for Der::val legal, or does it need to be the
>> exact name Base::val?  (One of my compilers says this is okay, and
>> another says it is not.)

Allan:
> I'm curious which compiler allows you to define Der::val?

Microsoft VC++ 5.0.  Surprised?

Me:
>> Assuming that it is legal, would this create a problem if I had
>> another derived class that inherited Base?:
>>     class Two: public Base
>>     {
>>     public:
>>         int foo()
>>         {
>>             return val;
>>         }
>>     };

Allan:
> This part actually *IS* legal.  Any class derived from Base can
> use val as if it was part of the class -- because it is.  But you
> should realize that there is one and only one val.  ...

Oh, I do.  I just wondered how many different ways it could be
spelled in its one single definition.

Apparently, MS-VC++ takes any definition of the member as long as
it is a member of *one* of the classes in the inheritance tree.
Which is a bug, of course.


-- David R. Tribble, dtribble@technologist.com --
-- C++, the PL/1 of the 90s.
[cut here, blanks added to satiate the newsreader]
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: AllanW@my-dejanews.com
Date: 1998/07/15
Raw View
In article <35ABFB58.2E4D@noSPAM.central.beasys.com>,
  dtribble@technologist.com wrote:
> >> Given the following code, is the definition of Der:val legal?:
> >>     class Base
> >>     {
> >>     public:
> >>         static int  val;
> >>     };
> >>
> >>     class Der: public Base
> >>     {
> >>         ...
> >>     };
> >>
> >>     /*static*/ int  Der::val = 2;   // Not Base::val
>
> >> Is the definition for Der::val legal, or does it need to be the
> >> exact name Base::val?  (One of my compilers says this is okay, and
> >> another says it is not.)

I responded:
> > I'm curious which compiler allows you to define Der::val?

> Microsoft VC++ 5.0.  Surprised?

Yes, very!  However, I tried it myself and it did work.

Then I tried defining both Base::val and Der::val.  The error message
is very illuminating:
    error C2374: 'public: static int  Base::val' : redefinition;
    multiple initialization
The line in question was the one defining Der::val, not Base::val as
the message states!

So why would the compiler do this?  The answer is that any REFERENCES
to Der::val should automatically be converted to Base::val.  That is,
the following should be legal:
    int x = Der::val; // Reads value of Base::val;
I suspect what happens is that the compiler does something similar to
inheritance, automatically converting Der::val to Base::val as soon
as the tokens have been parsed.  Thus, the illegal definition of
Der::val actually initialized Base::val.

This is certainly legal for a compiler to do, because it only affects
non-conforming programs (such as those that define Der::val instead
of Base::val).  But it is surprising, at least to me.

> >> Assuming that it is legal, would this create a problem if I had
> >> another derived class that inherited Base?:
> >>     class Two: public Base
> >>     {
> >>     public:
> >>         int foo()
> >>         {
> >>             return val;
> >>         }
> >>     };

> > This part actually *IS* legal.  Any class derived from Base can
> > use val as if it was part of the class -- because it is.  But you
> > should realize that there is one and only one val.  ...

> Oh, I do.  I just wondered how many different ways it could be
> spelled in its one single definition.

The definition can only be spelled one way: Base::val.  References,
however, can vary widely.

> Apparently, MS-VC++ takes any definition of the member as long as
> it is a member of *one* of the classes in the inheritance tree.
> Which is a bug, of course.

I don't think it's actually a bug, although it is surprising.  Again,
this only affects non-conforming programs; if your program is legal,
then the results are exactly as specified.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: David R Tribble <david.tribble@noSPAM.central.beasys.com>
Date: 1998/07/13
Raw View
Given the following code, is the definition of Der:val legal?:

    class Base
    {
    public:
        static int  val;
        ...
    };

    class Der: public Base
    {
        ...
    };

    /*static*/ int  Der::val = 2;   // Not Base::val

Is the definition for Der::val legal, or does it need to be the
exact name Base::val?  (One of my compilers says this is okay, and
another says it is not.)  (I guess this is also a question about how
the linker deals with this.)

Assuming that it is legal, would this create a problem if I had
another derived class that inherited Base?:

    class Two: public Base
    {
    public:
        int foo()
        {
            return val;
        }
        ...
    };

-- David R. Tribble, dtribble@technologist.com --
-- C++, the PL/1 of the 90s.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: AllanW@my-dejanews.com
Date: 1998/07/14
Raw View
In article <35AA94A2.C38@noSPAM.central.beasys.com>,
  dtribble@technologist.com wrote:
> Given the following code, is the definition of Der:val legal?:
>
>     class Base
>     {
>     public:
>         static int  val;
>         ...
>     };
You are required to define Base::val somewhere.
>
>     class Der: public Base
>     {
>         ...
>     };
>
>     /*static*/ int  Der::val = 2;   // Not Base::val
This is illegal because val wasn't defined in Der.  By the same
token, if you declared Base to have a member function bar(), you
wouldn't try to define Der::bar() explicitly -- you would know
that Der derives bar() from Base. The same thing happens to val.
(You could override bar() in the new class, but that's something
else completely.)

> Is the definition for Der::val legal, or does it need to be the
> exact name Base::val?  (One of my compilers says this is okay, and
> another says it is not.)  (I guess this is also a question about how
> the linker deals with this.)
I'm curious which compiler allows you to define Der::val?  This is
an error.

> Assuming that it is legal, would this create a problem if I had
> another derived class that inherited Base?:
>
>     class Two: public Base
>     {
>     public:
>         int foo()
>         {
>             return val;
>         }
>         ...
>     };
This part actually *IS* legal.  Any class derived from Base can
use val as if it was part of the class -- because it is.  But you
should realize that there is one and only one val.  So:

    class Der: public Base { public:
        int get_val() { return val; }
        void set_val(int newval) { val = newval; }
    };
    class Two: public Base { public:
        int get_val() { return val; }
    };
    bool isSame() {
        Der d;
        Two t;
        d.set_val(rand());
        return d.get_val() == t.get_val();
    }

Even though isBad() uses Der::set_val to set val to a random
number, isSame() will always return TRUE, because Der::get_val()
and Two::get_val() will *always* return the exact same value,
namely Base::val.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]