Topic: Reposting "Exposing private/protected members


Author: David R Tribble <david.tribble@noSPAM.central.beasys.com>
Date: 1998/11/26
Raw View
"Ajay Wanchoo" <wanchoo@caip.rutgers.edu> writes:
> I just want an opinion of the experts on the following situation:
> Should the exposing of private / protected members (as done below by
> B) be trapped by the compilers.
>
> class A
> {
>     private:
>         int a,b;
>     public:
>     A(){a = b = 0;}
> };
>
> class B
> {
>     public:
>         int a,b;
>     B(){a = b = 0;}
> }
>
> void main()
> {
>     A a;
>     B *b = (B*)(&a);   <---
>     cout << b->a;
> }

Steve Clamage wrote:
> Use of 'b' following the marked line has undefined results.
>
> When you use a cast, especially an old-style cast, you tell
> the compiler, "Trust me; I know what I'm doing." In this
> example, you should have no expectation that the code will
> have any predictable result. (Classes A and B need not have
> the same layout, since A is not a POD-struct.)
> ...

Exactly.  Casting between unrelated types like this is usually not
a good idea.  It's certainly not portable.

However, you can get closer to what you want by doing something
along these lines:

    struct Common
    {
        int   a, b;
    };

    class A
    {
    private:
        struct Common  c;
    public:
        ...
    };

    class B
    {
    private:
        struct Common  c;
    public:
        ...
    };

    void fiddle()
    {
        A    a;
        B *  b = (B*)(&a);   // <--
        cout << b->c.a;
    }

The marked line is still undefined behavior, but the layout of
A and B are more similar than before; A::c and B::c have exactly
the same member arrangement, even if A and B don't overall.

One further step in the the right direction is to use an accessor
function in A (which should probably be a friend of B) that allows
you to cast a pointer to a.c into a B::c pointer.

Of course, you're playing fast and loose with the type system of
C++ here.  Provided your casts are valid, I doubt you'll get any
useful warnings from your compiler, regardless of the danger
involved.

-- David R. Tribble, dtribble@technologist.com --
---
[ 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: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/11/18
Raw View
In article <3652F364.4B50EF68@acm.org>,
Pete Becker  <petebecker@acm.org> wrote:
>Please say more. I looked (somewhat cursorily) for wording in the
>standard that ruled this out, and didn't find any. As far as I can see,
>both A and B are PODs. They have the same number of members, and
>corresponding members have layout-compatible types, so they are
>layout-compatible. (that's a paraphrase of 9.2/15)

A POD cannot contain private data (it is an aggregate 9/4 and
aggregates cannot contain private data 8.5.1/1).

If POD were allowed to contain private/protected data lots of strange
would have happened.
--
// Home page  http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]




[ 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: Pete Becker <petebecker@acm.org>
Date: 1998/11/18
Raw View
Hans Olsson wrote:
>
> A POD cannot contain private data (it is an aggregate 9/4 and
> aggregates cannot contain private data 8.5.1/1).

Ah, that's the key. Thanks.

--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com
---
[ 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/11/20
Raw View
In article <72s87b$bk6$1@newsmonger.rutgers.edu>,
  "Ajay Wanchoo" <wanchoo@caip.rutgers.edu> wrote:
>
> I just want an opinion of the experts on the following situation:
> Should the exposing of private / protected members (as done below by B) be
> trapped by the compilers.
> class A
> {
>     private:
>         int a,b;
>     public:
>     A(){a = b = 0;}
> };
> class B
> {
>     public:
>         int a,b;
>     B(){a = b = 0;}
> }
> void main()
> {
>     A a;
>     B *b = (B*)(&a);
>     cout << b->a;
> }

This is not an instance of "exposing the private members" of A. This
is an instance of having members in B that happen to have the same
member names that members in A have. This does not deserve a warning.

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ 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: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1998/11/18
Raw View
"Ajay Wanchoo" <wanchoo@caip.rutgers.edu> writes:

>I just want an opinion of the experts on the following situation:
>Should the exposing of private / protected members (as done below by B) be
>trapped by the compilers.
>class A
>{
>    private:
>        int a,b;
>    public:
>    A(){a = b = 0;}
>};
>class B
>{
>    public:
>        int a,b;
>    B(){a = b = 0;}
>}
>void main()
>{
>    A a;
>    B *b = (B*)(&a);   <---
>    cout << b->a;
>}

Use of 'b' following the marked line has undefined results.

When you use a cast, especially an old-style cast, you tell
the compiler, "Trust me; I know what I'm doing." In this
example, you should have no expectation that the code will
have any predictable result. (Classes A and B need not have
the same layout, since A is not a POD-struct.)

The marked line itself is valid, in the sense that the line
itself breaks no language rules. A compiler could warn that
the cast is a bad idea, but most programmers don't want to be
warned about explicit old-style casts, even dangerous ones.

If you use one of the new-style casts, you have more language
rules available to help you. None of const_cast, static_cast,
or dynamic_cast is valid for the marked line, and the compiler
would emit a diagnostic message. The only valid cast for the
marked line is a reinterpret_cast, which announces that you are
doing something dangerous or unportable. A warning about a
reinterpret_cast would seem redundant.

Maybe you meant to ask whether you should get warnings about
hacking around access protection. The C++ type system was
designed to help protect against accidents, not against fraud.
Or, in my favorite formulation by Damian Conway, "C++ protects
against Murphy, not Machiavelli."

--
Steve Clamage, stephen.clamage@sun.com
---
[ 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: Pete Becker <petebecker@acm.org>
Date: 1998/11/18
Raw View
Steve Clamage wrote:
>
> >void main()
> >{
> >    A a;
> >    B *b = (B*)(&a);   <---
> >    cout << b->a;
> >}
>
> Use of 'b' following the marked line has undefined results.
>

Please say more. I looked (somewhat cursorily) for wording in the
standard that ruled this out, and didn't find any. As far as I can see,
both A and B are PODs. They have the same number of members, and
corresponding members have layout-compatible types, so they are
layout-compatible. (that's a paraphrase of 9.2/15)

--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com


[ 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: "Ajay Wanchoo" <wanchoo@caip.rutgers.edu>
Date: 1998/11/17
Raw View
I just want an opinion of the experts on the following situation:
Should the exposing of private / protected members (as done below by B) be
trapped by the compilers.
class A
{
    private:
        int a,b;
    public:
    A(){a = b = 0;}
};
class B
{
    public:
        int a,b;
    B(){a = b = 0;}
}
void main()
{
    A a;
    B *b = (B*)(&a);
    cout << b->a;
}




[ 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              ]