Topic: Casting


Author: Mourad or Rosalinda Ettaki <ettaki@mediaone.net>
Date: 1999/03/02
Raw View
Could someone tell me why this compiles:

main()
{
    int X;

    trythis((bool &)X);                // compiles !!!!!
    trythis((bool)X);                    // doesn't compile !!!!!
}

void trythis(bool& X)
{
}

Thanks!





[ 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: James.Kanze@dresdner-bank.com
Date: 1999/03/02
Raw View
In article <36DB3CDC.C7853685@mediaone.net>,
  ettaki@mediaone.net wrote:
>
> Could someone tell me why this compiles:
>
> main()
> {
>     int X;
>
>     trythis((bool &)X);                // compiles !!!!!

You can cast *anything* to a reference to *anything* using old style
casts.  Of course, just because it will compile doesn't mean is will
run:-).  If sizeof( bool ) happens to be the same as sizeof( int ), it
might appear to work, but accessing through the generated reference is
formally undefined behavior.

>     trythis((bool)X);                    // doesn't compile !!!!!

Because the result of a cast to anything but a reference is not an
lvalue, and only an lvalue can be bound to a non-const reference.

> }
>
> void trythis(bool& X)
> {
> }

--
James Kanze                                           GABI Software, S   rl
Conseils en informatique orient    objet  --
                          --  Beratung in industrieller Datenverarbeitung
mailto: kanze@gabi-soft.fr          mailto: James.Kanze@dresdner-bank.com

-----------== 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: jcoffin@taeus.com (Jerry Coffin)
Date: 1999/03/03
Raw View
In article <36DB3CDC.C7853685@mediaone.net>, ettaki@mediaone.net
says...
>
> Could someone tell me why this compiles:
>
> main()
> {
>     int X;
>
>     trythis((bool &)X);                // compiles !!!!!
>     trythis((bool)X);                    // doesn't compile !!!!!

The result of a cast is an rvalue, therefore to be passed as a
reference, it must be a reference to a const.

> void trythis(bool& X)

void trythis(bool const &X)

should work.  With this change, you won't need an explicit cast at
all.
---
[ 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: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/09/15
Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:

> Valentin Bonnard wrote:
> >
> > Steve Clamage <stephen.clamage@eng.sun.com> writes:
> >
> > > Matthew Ireland wrote:
> > > >
> > > > A discussion has come up at work about casting.  When I learned C++
> > > > there were two methods of casting available, the old c way:
> > > >         (int)SomeNumber
> > > > and a new c++ way
> > > >         int(SomeNumber)

[...]

> > > The fundamental problems with casts remained, in particular:
> > >
> > > 1. Casts are used for a variety of purposes
> >
> > IMO Pascal style should only be valid for implicit conversions
> > (like implicit_cast<>/convert<>).
>
> I agree - except that it should also enable explicit
> constructors to be called.
> Unfortunaly it's much too late to restrict them now...
>
> Also maybe it would add syntax problems:
>
> int* p=(int*)(&q+5); // C style or Pascal style cast?

Everything that isn't TypeName (expr) is a C style cast.
TypeName is a terminal in this case. int* is the name of
a type, but (int*) isn't.

And only Pascal style can be used to call multi-args
ctor 'Foo (x, y, z)'.

> > > The syntax ought to reflect the
> > > magnitude of what you are doing. (At least, that was the
> > > reasoning -- you don't have to agree.)
> >
> > And even static_cast is vague !
> >
> > I can perform different things:
> > - call a ctor
> > - convert between arithmetic types
> > - go to a base class
> > - go to a derived class
>
> That would lead to the following family of replacement casts:
>
> constructor_cast<>

No real need for this one, and it's limited anyway (what about
ctors with more than one argument).

> arithmetic_cast<>

narrow_arithmetic_cast<>
widen_arithmetic_cast<>

Or as in Caml Light:

float_of_int: int -> float
int_of_float: float -> int

etc... ;-)

> base_cast<>
> derived_cast<>
>
> But at least the last two could still be combined to
>
> hierarchic_cast<>
>
> as casts to base are implicit anyway (and therefore ned no cast
> att all). OTOH, hierarchic_cast should then be allowed to cast to
> private bases, as well.
>
> In addition, the first two could be seen as equivalent, as
> converting an int to a long could well be seen as constructing
> a long, thus as an implicit constructor call. Also, it would be
> strange to have to do (assuming i is int)
>
> arithmethic_cast<long>(i)
>
> but
>
> constructor_cast<BigInt>(i)

Yes

> And then, there are also type conversiopn operators, not addressed
> at all with this classification.
> So those meanings should also be merged, leaving us with two
> substantially different replacements for static_cast<>:
>
> conversion_cast<> (constructor call, conversion operator, arithmetic)

Only non-explicit constructor call; I'd call that convert<>

> hierarchic_cast<> (should also allow navigating privat bases)

I like the name static_cast<> for this purpose; I like to have
a short name for safe casts (arithmethic_cast U constructor_cast),
like convert<>.

> Of course it's too late for those two, as well...

Of course

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ 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: Mark Wilden <Mark@mWilden.com>
Date: 1997/09/04
Raw View
Hans Aberg wrote:
>
> In article <3406E633.6375@xcellenet.--->, Matthew Ireland
> <matthew.ireland@xcellenet.---> wrote:
>
>  >        int(SomeNumber)
>  >
>  >The latter was in certain situations clearer especially if "SomeNumber"
>  >was replaced by an expression.
>  >
>  >Now I have been told that both of these are replaced by
>  >
>  >static_cast< typeid >( expression )
>  >dynamic_cast< typeid >( expression )
>  >const_cast< typeid >( expression )
>  >reinterpret_cast< typeid >( expression )
>  >
>  >which seems to me to be overkill when I am just trying to make sure that
>  >any promotion done to do a calculation or some constant is in the form I
>  >want it to be.
>
>   I am not sure the one style excludes the other: The first type of casts
> are compile time casts, and the latter are run-time casts (when moving
> over a class hierarchy). Or so was my impression.

In my understanding, only dynamic_cast has any runtime component. The
others are simply ways to restrict the type of casting performed,
instead of the wholesale abandonment of static typing. They're better
than either of the unrestricted cast styles for that reason, but also
because they are searchable, they stick out like sore thumbs (which they
are) and they require more typing.  The latter two reasons make them
even more likely to be avoided except when strictly necessary, which is
a good thing.
---
[ 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: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/09/06
Raw View
Steve Clamage <stephen.clamage@eng.sun.com> writes:

> Matthew Ireland wrote:
> >
> > A discussion has come up at work about casting.  When I learned C++
> > there were two methods of casting available, the old c way:
> >         (int)SomeNumber
> > and a new c++ way
> >         int(SomeNumber)
>
> That is approximately correct. The "new" style goes back to
> very early versions of C++. The two forms were allowed
> because neither form alone could perform all possible
> C++ casts.

But there wasn't any need to be able to perform all old-style
casts with a Pascal style cast.

> The fundamental problems with casts remained, in particular:
>
> 1. Casts are used for a variety of purposes

IMO Pascal style should only be valid for implicit conversions
(like implicit_cast<>/convert<>).

> 2. You can't use a text editor to locate casts in a program.
> You need a complete C++ parse of the code, and a browser
> that can be told to look for casts. Since casts always
> should be examined when porting a program, being unable to
> find casts easily is a real hinderance to reliable programming.
>
> > Now I have been told that both of these are replaced by
> >
> > static_cast< typeid >( expression )
> > dynamic_cast< typeid >( expression )
> > const_cast< typeid >( expression )
> > reinterpret_cast< typeid >( expression )
> >
> > which seems to me to be overkill when I am just trying to make sure that
> > any promotion done to do a calculation or some constant is in the form I
> > want it to be.

I agree:

static_cast<Der&> (base_ref)

is more readable than: (Der&) base_ref

> Certainly it means more text to write and read, but that was
> intentional. Nearly all safe conversions are implicit in C++,
> and no explicit cast needs to be written.

It depends what you call a need:

surf = long (right - left) * (bottom - top);

can be written:

long dx = right - left;
surf = dx * (bottom - top);

but I don't think it's more readable (especialy if you are
not going to use dx again).

> If you write a
> necessary cast, it means you are doing something potentially
> dangerous or non-portable.

Not in this case

> The syntax ought to reflect the
> magnitude of what you are doing. (At least, that was the
> reasoning -- you don't have to agree.)

And even static_cast is vague !

I can perform different things:
- call a ctor
- convert between arithmetic types
- go to a base class
- go to a derived class

--

Valentin Bonnard
mailto:bonnardv@pratique.fr
http://www.pratique.fr/~bonnardv (Informations sur le C++ en Francais)
---
[ 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: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/09/08
Raw View

Valentin Bonnard wrote:
>
> Steve Clamage <stephen.clamage@eng.sun.com> writes:
>
> > Matthew Ireland wrote:
> > >
> > > A discussion has come up at work about casting.  When I learned C++
> > > there were two methods of casting available, the old c way:
> > >         (int)SomeNumber
> > > and a new c++ way
> > >         int(SomeNumber)
> >
> > That is approximately correct. The "new" style goes back to
> > very early versions of C++. The two forms were allowed
> > because neither form alone could perform all possible
> > C++ casts.
>
> But there wasn't any need to be able to perform all old-style
> casts with a Pascal style cast.
>
> > The fundamental problems with casts remained, in particular:
> >
> > 1. Casts are used for a variety of purposes
>
> IMO Pascal style should only be valid for implicit conversions
> (like implicit_cast<>/convert<>).
>

I agree - except that it should also enable explicit
constructors to be called.
Unfortunaly it's much too late to restrict them now...

Also maybe it would add syntax problems:

int* p=(int*)(&q+5); // C style or Pascal style cast?

[...]

> > The syntax ought to reflect the
> > magnitude of what you are doing. (At least, that was the
> > reasoning -- you don't have to agree.)
>
> And even static_cast is vague !
>
> I can perform different things:
> - call a ctor
> - convert between arithmetic types
> - go to a base class
> - go to a derived class

That would lead to the following family of replacement casts:

constructor_cast<>
arithmetic_cast<>
base_cast<>
derived_cast<>

But at least the last two could still be combined to

hierarchic_cast<>

as casts to base are implicit anyway (and therefore ned no cast
att all). OTOH, hierarchic_cast should then be allowed to cast to
private bases, as well.

In addition, the first two could be seen as equivalent, as
converting an int to a long could well be seen as constructing
a long, thus as an implicit constructor call. Also, it would be
strange to have to do (assuming i is int)

arithmethic_cast<long>(i)

but

constructor_cast<BigInt>(i)

And then, there are also type conversiopn operators, not addressed
at all with this classification.
So those meanings should also be merged, leaving us with two
substantially different replacements for static_cast<>:

conversion_cast<> (constructor call, conversion operator, arithmetic)
hierarchic_cast<> (should also allow navigating privat bases)

Of course it's too late for those two, as well...
---
[ 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: "Paul D. DeRocco" <pderocco@ix.netcom.crud.com>
Date: 1997/08/31
Raw View
Matthew Ireland wrote:
>
> A discussion has come up at work about casting.  When I learned C++
> there were two methods of casting available, the old c way:
>
>         (int)SomeNumber
>
> and a new c++ way
>
>         int(SomeNumber)
>
> The latter was in certain situations clearer especially if "SomeNumber"
> was replaced by an expression.
>
> Now I have been told that both of these are replaced by
>
> static_cast< typeid >( expression )
> dynamic_cast< typeid >( expression )
> const_cast< typeid >( expression )
> reinterpret_cast< typeid >( expression )
>
> which seems to me to be overkill when I am just trying to make sure that
> any promotion done to do a calculation or some constant is in the form I
> want it to be.

I also think the new casts are semantic (and typographic) overkill when
doing trivial numeric casts. I reserve them for operations involving
non-numeric types.

--

Ciao,
Paul

(Please remove the extra "crud" from the return address,
which has been altered to foil junk mail senders.)
---
[ 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
]