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 ]