Topic: Dereferencing pointer to incomplete class


Author: jbarfurth@vossnet.de (Joerg Barfurth)
Date: 1999/11/27
Raw View
Gerhard Menzl <gerhard.menzl@sea.ericsson.se> wrote:

> The two compilers I am using disagree on whether the following code is
> well-formed:
>=20
>=20
>    struct F;
>=20
>    struct S
>    {
>       S (F& f) : my_f (f) {}
>       F& my_f;
>    }
>=20
>    void h (F* pf)
>    {
>       S* ps =3D new S (*pf);   // <--- line in doubt
>    }
>=20
> The question is whether it is legal to dereference a pointer to an inco=
mplete
> type in order to initialize a reference to the same type. From a heuris=
tical
> point of view, this should be okay, as the incomplete type is never use=
d, and
> its size is not required. However, I am uncertain about the following p=
assage
> in the standard (3.2/4):
At the end of 5.3.1/1 there is a note:
"Note: a pointer to an incomplete type (other than cv void) can be
dereferenced. The lvalue thus obtained can be used in limited ways (to
initialize a reference, for example); this lvalue must not be converted
to an rvalue, see 4.1."

While this is not normative, I would consider it to be more than
heuristical support.

> "A class type T must be complete if:
>=20
> [...]
>=20
> - an expression that is not a null-pointer constant, and has type other=
 than
> void *, is converted to the type pointer to T or reference to T using a=
n
> implicit conversion (clause 4), a dynamic_cast (5.2.7) or a static_cast
> (5.2.9)"
>=20
> As far as I know, dereferencing T* in order to initialize a T& does not
> qualify as an implicit conversion, but I would like to be certain befor=
e I
> submit a bug report to the compiler vendor.
There are no conversions involved in the above code. By 8.5.3 the lvalue
is bound directly to the reference (no conversion required).

> Gerhard Menzl

-- J=F6rg Barfurth
---
[ 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: wmm@fastdial.net
Date: 1999/11/27
Raw View
In article <1e1r18m.yuelmi1wa47jlN@dialina46.bn.hh.vossnet.de>,
  jbarfurth@vossnet.de (Joerg Barfurth) wrote:
> At the end of 5.3.1/1 there is a note:
> "Note: a pointer to an incomplete type (other than cv void) can be
> dereferenced. The lvalue thus obtained can be used in limited ways (to
> initialize a reference, for example); this lvalue must not be
converted
> to an rvalue, see 4.1."
>
> While this is not normative, I would consider it to be more than
> heuristical support.

The normative statement of this rule is not a statement at all,
rather, it's the absence of anything that would require a complete
type in such circumstances.  Because it's often difficult to make
conclusions from the absence of a specification, the note was added
to make things easier on the reader.
--
William M. Miller, wmm@fastdial.net
OnDisplay, Inc. (www.ondisplay.com)


Sent via Deja.com http://www.deja.com/
Before you buy.


[ 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: Gerhard Menzl <gerhard.menzl@sea.ericsson.se>
Date: 1999/11/23
Raw View
The two compilers I am using disagree on whether the following code is
well-formed:


   struct F;

   struct S
   {
      S (F& f) : my_f (f) {}
      F& my_f;
   }

   void h (F* pf)
   {
      S* ps = new S (*pf);   // <--- line in doubt
   }

The question is whether it is legal to dereference a pointer to an incomplete
type in order to initialize a reference to the same type. From a heuristical
point of view, this should be okay, as the incomplete type is never used, and
its size is not required. However, I am uncertain about the following passage
in the standard (3.2/4):

"A class type T must be complete if:

[...]

- an expression that is not a null-pointer constant, and has type other than
void *, is converted to the type pointer to T or reference to T using an
implicit conversion (clause 4), a dynamic_cast (5.2.7) or a static_cast
(5.2.9)"

As far as I know, dereferencing T* in order to initialize a T& does not
qualify as an implicit conversion, but I would like to be certain before I
submit a bug report to the compiler vendor.

Gerhard Menzl


[ 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: wmm@fastdial.net
Date: 1999/11/23
Raw View
In article <383A616E.B8526A50@sea.ericsson.se>,
  Gerhard Menzl <gerhard.menzl@sea.ericsson.se> wrote:
>
> The two compilers I am using disagree on whether the following code is
> well-formed:
>
>    struct F;
>
>    struct S
>    {
>       S (F& f) : my_f (f) {}
>       F& my_f;
>    }
>
>    void h (F* pf)
>    {
>       S* ps = new S (*pf);   // <--- line in doubt
>    }
>
> The question is whether it is legal to dereference a pointer to an
incomplete
> type in order to initialize a reference to the same type. From a
heuristical
> point of view, this should be okay, as the incomplete type is never
used, and
> its size is not required. However, I am uncertain about the following
passage
> in the standard (3.2/4):
>
> "A class type T must be complete if:
>
> [...]
>
> - an expression that is not a null-pointer constant, and has type
other than
> void *, is converted to the type pointer to T or reference to T using
an
> implicit conversion (clause 4), a dynamic_cast (5.2.7) or a
static_cast
> (5.2.9)"
>
> As far as I know, dereferencing T* in order to initialize a T& does
not
> qualify as an implicit conversion, but I would like to be certain
before I
> submit a bug report to the compiler vendor.

That paragraph in 3.2 is unrelated to this particular expression,
as you suggested.  That's intended to prevent pointer conversions
between two class types that are unrelated in the context of the
conversion but are in fact related by inheritance -- you must have
seen the complete definition of the type in order to make sure.

Your question is answered specifically in the note in 5.3.1p1: "A
pointer to an incomplete type (other than cv void) can be dereferenced.
The lvalue thus obtained can be used in limited ways (to initialize a
reference, for example); this lvalue must not be converted to an
rvalue, see 4.1."
--
William M. Miller, wmm@fastdial.net
OnDisplay, Inc. (www.ondisplay.com)


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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              ]