Topic: Quick questions


Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1996/03/28
Raw View
Andrew Bell (abell@mindspring.com) wrote:
| No, I'd want to go the other way.  In the case of "pure wrapper"
| classes (as I defined in my earlier post), one might want an automatic
| cast from the original to the wrapper.  In my case, I have created a
| class to wrap around an OS-defined struct, to give it access safety
| (the particular class contains a type specifier and a union) and
| smarter access as well as constructors.

| I'd like to have a casting operator that would allow me to convert the
| original struct to the pure wrapper automatically.

You do realise that you aren't guaranteed the behaviour that you obviously
want in Standard C++, don't you ?

A simple version of your scenario, in code, is :

 struct SOMETHING { // Arbitrary O/S API POD-struct
  int i ;
  char buf[9] ;
 } ;

 struct Something : public SOMETHING {
  Something() : i(7) { buf[0] = '\000' ; }
 } ;

What you want is to be able to substitute `Something' wherever your O/S
API requires a `SOMETHING'.

Unfortunately, Standard C++ doesn't guarantee that the address of a base
class subobject is the same as the address of the complete object.  In other
words, casting from `Something *' to `SOMETHING *' might involve an offset
calculation.  This isn't particularly difficult or bothersome when calling
the O/S API, since the compiler will handle passing a `Something *' to an
O/S API function that expects a `SOMETHING *'.

However, if an O/S API function _returns_ a `SOMETHING *', then assigning
the result into a `Something *' is not only wrong (Standard C++ will
require you to use a cast) but dangerous.  The danger lies in the fact that
the C++ implementation may require extra housekeeping information in a
`Something' (because it is a derived class, because it has function
members, or for some other reason), which simply won't be in the
`SOMETHING' object the address of which was returned to you by the O/S API.

The flaw in your original message was assuming that not having virtual
function members is the only requirement for being a POD-struct.  If you
look at [dcl.init.aggregate] and [class] you will find that there is quite
a long list of prohibitions on POD-structs, including not having base
classes.

You can tell that I've trod this road as well, can't you ?  (-:

| (but you can't always get what you want...)

Exactly.
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Wil Evers" <wil@ittpub.nl>
Date: 1996/03/28
Raw View
In article <4jajk2$17aq@mule1.mindspring.com> abell@mindspring.com (Andrew
Bell) writes:

> clamage@Eng.sun.com (Steve Clamage) wrote:
> [snip]
>
> >I assume you mean a class like
> >     class Short { short val; };
> >with non-virtual member functions added. You can't assume the size and
> >alignment of the class will be the same as its only data member, and
> >no, the standard provides no special support for this special case.
>
> Seems like if you only have one data member and no virtual functions,
> there's no reason to arbitrarily restrict it to a greater alignment
> level, save maybe to make compiler programmer's lives (and maybe
> debugger programmer's lives) trivially easier.

I few weeks ago, I ran into a similar problem (I was wrapping a struct around a
plain character array, which unexpectely changed its alignment), and I did some
enquires on comp.std.c.

It turns out some platforms have different optimal pointer representations
depending on the alignment of what's being pointed to. Since you don't need to
define a structure before you declare a pointer to it, assuming all structures
are maximally aligned "just because they're structures" may actually result in
more efficient code on these machines.

- Wil


[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1996/03/28
Raw View
In article <4jajk2$17aq@mule1.mindspring.com> abell@mindspring.com
(Andrew Bell) writes:

|> clamage@Eng.sun.com (Steve Clamage) wrote [but much edited by me]:
|> >In article 1e7a@mule1.mindspring.com, abell@mindspring.com (Andrew Bell) writes:
|> >>About casting operators]
|> >[[Are you asking] can you define
|> >a conversion operator from a user-defined class to a predefined type

|> No, I'd want to go the other way.  In the case of "pure wrapper"
|> classes (as I defined in my earlier post), one might want an automatic
|> cast from the original to the wrapper.  In my case, I have created a
|> class to wrap around an OS-defined struct, to give it access safety
|> (the particular class contains a type specifier and a union) and
|> smarter access as well as constructors.

You have it the other way.  The conversion operator is called a
constructor.  Thus, to take a concrete example (based on the deleted
parts of your posting (`stat' is a struct defined by Posix):

    class FileStat : stat
    {
    public :
                        FileStat( stat const& other ) ;
        //  ...
    } ;

If you have a (C) struct stat, it will convert automatically to a
FileStat.  (You can pass it to a function expecting a FileStat, for
example.)
--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
                            -- Beratung in industrieller Datenverarbeitung
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: abell@mindspring.com (Andrew Bell)
Date: 1996/04/01
Raw View
kanze@gabi-soft.fr (J. Kanze) wrote:
>You have it the other way.  The conversion operator is called a
>constructor.  Thus, to take a concrete example (based on the deleted
>parts of your posting (`stat' is a struct defined by Posix):

>    class FileStat : stat
>    {
>    public :
>                        FileStat( stat const& other ) ;
>        //  ...
>    } ;

That's fine when your base class is a small thing; not so good when
you're dealing with a large bitmap or (in my case) a Windows OLE
variant structure, or if you want it passed as a non-const parm.  Few
compilers would do the implicit conversion without creating a
temporary; none would do so if we have any logic at all in the
constructor, for example if our derived class shouldn't apply to all
versions of the base class.

Andrew Bell
abell@mindspring.com
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: abell@mindspring.com (Andrew Bell)
Date: 1996/03/25
Raw View
Hopefully these will have short answers, and aren't inappropriate for
the newsgroup.

1) Is there any way to catch an exception thrown in the constructor of
a statically constructed object?  Does it call unexpected() or
terminate() even?

2) From a previous post on this group, it looks like the standard will
allow one to define conversion operators for pre-existing, source code
untouchable data types.  Yes? No? What will this look like? I have the
May copy of the WP, and don't see any mention of this.

3) I often write what I call "pure wrapper" classes to give access
protection and data abstraction to pre-existing data types.  A pure
wrapper class is a class that adds no member variables or virtual
member functions to a class/struct that has no virtual functions of
its own, so their size and alignment should be the same and casting
between the two should be perfectly safe.  The new standard doesn't
have any special support (for example, allowing it automatically) for
this, does it?

4) With RTTI, a derived class that doesn't change any virtual member
funcs or add any properties to a base class still evaluates to a
different object type, correct?

Thanks for any and all answers.

Andrew Bell
abell@mindspring.com
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: clamage@Eng.sun.com (Steve Clamage)
Date: 1996/03/26
Raw View
In article 1e7a@mule1.mindspring.com, abell@mindspring.com (Andrew Bell) writes:

>2) From a previous post on this group, it looks like the standard will
>allow one to define conversion operators for pre-existing, source code
>untouchable data types.  Yes? No? What will this look like? I have the
>May copy of the WP, and don't see any mention of this.

I'm not sure I understand what you are asking. If you mean can you define
a conversion operator from a user-defined class to a predefined type
like int or double, then yes, that has long been part of C++.
 class myclass {
 public:
  operator int() { ... }
 };

>3) I often write what I call "pure wrapper" classes to give access
>protection and data abstraction to pre-existing data types.  A pure
>wrapper class is a class that adds no member variables or virtual
>member functions to a class/struct that has no virtual functions of
>its own, so their size and alignment should be the same and casting
>between the two should be perfectly safe.  The new standard doesn't
>have any special support (for example, allowing it automatically) for
>this, does it?

I assume you mean a class like
 class Short { short val; };
with non-virtual member functions added. You can't assume the size and
alignment of the class will be the same as its only data member, and no,
the standard provides no special support for this special case.

Example: It is common for shorts to be aligned on 2-byte boundaries,
but all structured types to require alignment on 4-byte boundaries.
In this case, all struct types would have a size which is a
multiple of 4.  Casting between short* and Short*, or between
short& and Short&, could cause problems.

>4) With RTTI, a derived class that doesn't change any virtual member
>funcs or add any properties to a base class still evaluates to a
>different object type, correct?

Yes. The typeids of two types compare equal if and only if they are
the same type. Base and derived classes are not ever the same type.

---
Steve Clamage, stephen.clamage@eng.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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de>
Date: 1996/03/26
Raw View
In article <4j5b26$1e7a@mule1.mindspring.com> abell@mindspring.com
(Andrew Bell) writes:

|> Hopefully these will have short answers, and aren't inappropriate for
|> the newsgroup.

|> 1) Is there any way to catch an exception thrown in the constructor of
|> a statically constructed object?  Does it call unexpected() or
|> terminate() even?

Exactly.  There is no way to catch the exception, so terminate will be
called.

|> 2) From a previous post on this group, it looks like the standard will
|> allow one to define conversion operators for pre-existing, source code
|> untouchable data types.  Yes? No? What will this look like? I have the
|> May copy of the WP, and don't see any mention of this.

I'm not sure what you mean here.  You have always been able to define
conversion operators for pre-existing types to *NEW* types; such
operators are called constructors:-).  If you mean somehow change the
meaning of e.g.: int->long, then I don't think that there is the
slightest chance of this being supported.

|> 3) I often write what I call "pure wrapper" classes to give access
|> protection and data abstraction to pre-existing data types.  A pure
|> wrapper class is a class that adds no member variables or virtual
|> member functions to a class/struct that has no virtual functions of
|> its own, so their size and alignment should be the same and casting
|> between the two should be perfectly safe.  The new standard doesn't
|> have any special support (for example, allowing it automatically) for
|> this, does it?

I'd like something like this too.  I often derive for the sole purpose
of changing the default constructor.

The only place where this is really an issue, however, is in arrays.
And since vector uses the copy constructor (rather than the default
constructor) to initialize, IMHO, it is no longer an issue there,
either.

So while some added guarantees might be nice, they really aren't worth
the effort it would take to define them.

|> 4) With RTTI, a derived class that doesn't change any virtual member
|> funcs or add any properties to a base class still evaluates to a
|> different object type, correct?

One would certainly hope so.  I cannot think of any reason why it would
be different.

--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils,    tudes et r   alisations en logiciel orient    objet --
                -- A la recherche d'une activit    dans une region francophone
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: clamage@Eng.sun.com (Steve Clamage)
Date: 1996/03/26
Raw View
In article 67891262@sqarc.sq.com, clamage@taumet.eng.sun.com (Steve Clamage) writes:
>clamage@Eng.sun.com (Steve Clamage) wrote:

>>>2) From a previous post on this group, it looks like the standard will
>>>allow one to define conversion operators for pre-existing, source code
>>>untouchable data types.  Yes? No? What will this look like? I have the
>>>May copy of the WP, and don't see any mention of this.
>>
>>I'm not sure I understand what you are asking. If you mean can you define
>>a conversion operator from a user-defined class to a predefined type
>>like int or double, then yes, that has long been part of C++.

>I believe he was referring to something like

>class myclass{};
>operator int(const myclass &arg);
>
>Just like the global equality operators, etc.

That is not allowed. A type conversion function must be a member of a class.

class myclass {
public:
 operator int(); // converts a myclass to an int
 myclass(int); // converts an int to a myclass
};

---
Steve Clamage, stephen.clamage@eng.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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: clamage@taumet.eng.sun.com (Steve Clamage)
Date: 1996/03/26
Raw View
clamage@Eng.sun.com (Steve Clamage) wrote:

>>2) From a previous post on this group, it looks like the standard will
>>allow one to define conversion operators for pre-existing, source code
>>untouchable data types.  Yes? No? What will this look like? I have the
>>May copy of the WP, and don't see any mention of this.
>
>I'm not sure I understand what you are asking. If you mean can you define
>a conversion operator from a user-defined class to a predefined type
>like int or double, then yes, that has long been part of C++.

I believe he was referring to something like

class myclass{};
operator int(const myclass &arg);

Just like the global equality operators, etc.



[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: willer@carolian.com (Steve Willer)
Date: 1996/03/27
Raw View
clamage@Eng.sun.com (Steve Clamage) wrote:

>>2) From a previous post on this group, it looks like the standard will
>>allow one to define conversion operators for pre-existing, source code
>>untouchable data types.  Yes? No? What will this look like? I have the
>>May copy of the WP, and don't see any mention of this.
>
>I'm not sure I understand what you are asking. If you mean can you define
>a conversion operator from a user-defined class to a predefined type
>like int or double, then yes, that has long been part of C++.

I believe he was referring to something like

class myclass{};
operator int(const myclass &arg);

Just like the global equality operators, etc.
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: abell@mindspring.com (Andrew Bell)
Date: 1996/03/27
Raw View
clamage@Eng.sun.com (Steve Clamage) wrote [but much edited by me]:
>In article 1e7a@mule1.mindspring.com, abell@mindspring.com (Andrew Bell) writes:
>>About casting operators]
>[[Are you asking] can you define
>a conversion operator from a user-defined class to a predefined type

No, I'd want to go the other way.  In the case of "pure wrapper"
classes (as I defined in my earlier post), one might want an automatic
cast from the original to the wrapper.  In my case, I have created a
class to wrap around an OS-defined struct, to give it access safety
(the particular class contains a type specifier and a union) and
smarter access as well as constructors.

I'd like to have a casting operator that would allow me to convert the
original struct to the pure wrapper automatically.  (but you can't
always get what you want...)  A constructor works differently than a
casting operator; in this case, it would force the creation of an an
(algorithmically) unnecessary duplicate object.  Admittedly, it's only
relevant for pure wrapper classes, but is that such a rare concept?

It's always seemed a little odd to me that you can add operators to a
class outside the class structure, even when they might modify the
object (such as ostream operator<<...), but not non-virtual functions.
It is, after all, this restriction against defining member functions
externally that leads to my need for pure wrapper classes (and my
desire for casting support to them) in the first place.

I can do what I need with dangerous casts
 PureWrapperClass &wrapper = (PureWrapperClass &)
  baseStruct;
but it isn't obvious without lots of hunting that this is in fact
safe.  Also, sometimes I might not want to allow the conversion (throw
an exception in the conversion operator),, which this approach doesn't
allow.

>I assume you mean a class like
> class Short { short val; };
>with non-virtual member functions added. You can't assume the size and
>alignment of the class will be the same as its only data member, and no,
>the standard provides no special support for this special case.

Seems like if you only have one data member and no virtual functions,
there's no reason to arbitrarily restrict it to a greater alignment
level, save maybe to make compiler programmer's lives (and maybe
debugger programmer's lives) trivially easier.   (For that matter, is
there really a good reason to make it more restrictive than the most
restrictive member element regardless of the number of elements?  I
suppose there's making the bitwise copy constructors a little more
efficient, though that doesn't hold for the single member case.)

>>4) With RTTI, a derived class that doesn't change any virtual member
>>funcs or add any properties to a base class still evaluates to a
>>different object type, correct?
>Yes. The typeids of two types compare equal if and only if they are
>the same type. Base and derived classes are not ever the same type.

Fair enough, although in this case RTTI forces the creation of an
additional vtable that wouldn't normally be necessary.  Since the
general criterion for RTTI support in a class in the first place is
the existence of any virtual functions (and thus a vtable), it doesn't
seem like it would be too unreasonable to make classes with identical
vtables evaluate to the same thing.  Adding an operator to a class
(externally) doesn't change its identity; should a non-virtual member
function do so?

Andrew Bell
abell@mindspring.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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]