C++ casts

Discussion in 'C++' started by Alf P. Steinbach, Aug 15, 2005.

  1. * Jacob:
    > It is a common recommendation to use
    > "static_cast<SomeType> someInstance" instead of the
    > traditional infamous "(SomeType) someInstance".
    >
    > Should I use the same practice for simple types,
    > i.e. instead of:
    >
    > double fraction = (double) n / total;
    >
    > should I write this?
    >
    > double fraction = static_cast<double>(n) /
    > static_cast<double>(total);
    >
    > I find the traditional version a lot more readable
    > in this case.


    There are at least three reasons why it's a Good Idea (TM) to use the C++
    named casts also for simple built-in types:

    * It helps you and maintainers of your code remember to not use C-style
    casts in general, which can help to prevent accidental usage.

    * C-style casts can do const_cast and reinterpret_cast, which you probably
    don't want (especially not for pointer values).

    * The type definitions may be changed when the code is maintained.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Aug 15, 2005
    #1
    1. Advertising

  2. Alf P. Steinbach

    Jacob Guest

    It is a common recommendation to use
    "static_cast<SomeType> someInstance" instead of the
    traditional infamous "(SomeType) someInstance".

    Should I use the same practice for simple types,
    i.e. instead of:

    double fraction = (double) n / total;

    should I write this?

    double fraction = static_cast<double>(n) /
    static_cast<double>(total);

    I find the traditional version a lot more readable
    in this case.

    Thanks!
     
    Jacob, Aug 15, 2005
    #2
    1. Advertising

  3. Alf P. Steinbach

    benben Guest

    "Jacob" <> wrote in message
    news:...
    > It is a common recommendation to use
    > "static_cast<SomeType> someInstance" instead of the
    > traditional infamous "(SomeType) someInstance".
    >
    > Should I use the same practice for simple types,
    > i.e. instead of:
    >
    > double fraction = (double) n / total;
    >
    > should I write this?
    >
    > double fraction = static_cast<double>(n) /
    > static_cast<double>(total);
    >
    > I find the traditional version a lot more readable
    > in this case.


    This is TRUE! The traditional version DOES feel a lot natural than the C++
    new cast operators.

    But this is EXACTLY why C++ cast operators look this way: they are so ugly
    looking to discourage you and alert you from using them. And you can always
    pick up all casts using a find in a text editor.

    >
    > Thanks!
     
    benben, Aug 15, 2005
    #3
  4. Alf P. Steinbach

    Guest

    Is the equivilent of
    double fraction = (double) n / total;
    really
    double fraction = static_cast<double>(n) / total;

    double fraction = (double) n / (double) total;

    isn't that readable either
     
    , Aug 15, 2005
    #4
  5. Alf P. Steinbach

    Greg Guest

    Jacob wrote:
    > It is a common recommendation to use
    > "static_cast<SomeType> someInstance" instead of the
    > traditional infamous "(SomeType) someInstance".
    >
    > Should I use the same practice for simple types,
    > i.e. instead of:
    >
    > double fraction = (double) n / total;
    >
    > should I write this?
    >
    > double fraction = static_cast<double>(n) /
    > static_cast<double>(total);
    >
    > I find the traditional version a lot more readable
    > in this case.
    >


    You should avoid casts altogether and write it the C++ way:

    double fraction = double(n) / double(total);

    assuming that n and total are both a scalar value type convertible to a
    double.

    Greg
     
    Greg, Aug 15, 2005
    #5
  6. * Jacob:
    > Greg wrote:
    >
    > > You should avoid casts altogether and write it the C++ way:
    > >
    > > double fraction = double(n) / double(total);
    > >


    This is not "the C++ way": using C casts is the way of C programmers.


    > > assuming that n and total are both a scalar value type convertible to a
    > > double.

    >
    > I like this.


    It's C-style casts, expressed in C++ functional notation.

    'T(v)' is equivalent to '(T)v'.


    > I did search for backing on this syntax
    > originally but neither S. Meyers nor A. Sutter mentions
    > it. And my colleges didn't knew about it.
    >
    > Could you please back it with some links?


    §5.2.3/1.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Aug 15, 2005
    #6
  7. Alf P. Steinbach

    Jacob Guest

    benben wrote:

    > But this is EXACTLY why C++ cast operators look this way: they are so ugly
    > looking to discourage you and alert you from using them. And you can always
    > pick up all casts using a find in a text editor.


    So did they really invent this ugly syntax so I
    shouldn't use casting, or is this just an urban
    myth?

    I'd guess there are people from academia telling you
    not to cast ever, but no industry scale C++ system
    can do without it. And how can I find the fraction of
    int 10 to int 35 without casting?

    And why do I need a syntax so that _Notepad_ can tell
    me where my casts are? First, I wouldn't categorize
    code by casts (I don't need a way to find them all),
    and a _proper_ editor would tell me (if asked) anyway.

    Isn't it so that static_cast (and its cousins) is an
    aid for the compiler to to proper type checking and
    that neither the compiler nor the runtime environment
    can help me when trying to find the fraction of two
    integers?

    Thanks!
     
    Jacob, Aug 15, 2005
    #7
  8. Alf P. Steinbach

    Guest

    Jacob skrev:

    > benben wrote:
    >
    > > But this is EXACTLY why C++ cast operators look this way: they are so ugly
    > > looking to discourage you and alert you from using them. And you can always
    > > pick up all casts using a find in a text editor.

    >
    > So did they really invent this ugly syntax so I
    > shouldn't use casting, or is this just an urban
    > myth?


    I heard that reinterpret_cast was made purposefully ackward to
    discourage its use.

    >
    > I'd guess there are people from academia telling you
    > not to cast ever, but no industry scale C++ system
    > can do without it. And how can I find the fraction of
    > int 10 to int 35 without casting?


    I doubt any from academia would tell you never to cast, but casting the
    C++ way really is much better. Casting in C++ is much rarer than in C,
    however.

    >
    > And why do I need a syntax so that _Notepad_ can tell
    > me where my casts are? First, I wouldn't categorize
    > code by casts (I don't need a way to find them all),
    > and a _proper_ editor would tell me (if asked) anyway.


    Well, finding casts is not easy when you use C-syntax. But the primary
    raison d'etre for the new casts is that you tell precisely what kind of
    cast you're performing.
    >
    > Isn't it so that static_cast (and its cousins) is an
    > aid for the compiler to to proper type checking and
    > that neither the compiler nor the runtime environment
    > can help me when trying to find the fraction of two
    > integers?


    There is no aid whatsoever to the compiler. There's a huge aid to the
    reader of your code - yourself a half year later or one of your
    collegues. A traditional C-style cast does not tell you anything, and
    you do cast away const amongst other things. Don't use them.

    >
    > Thanks!


    /Peter
     
    , Aug 15, 2005
    #8
  9. Alf P. Steinbach

    Jacob Guest

    Greg wrote:

    > You should avoid casts altogether and write it the C++ way:
    >
    > double fraction = double(n) / double(total);
    >
    > assuming that n and total are both a scalar value type convertible to a
    > double.


    I like this. I did search for backing on this syntax
    originally but neither S. Meyers nor A. Sutter mentions
    it. And my colleges didn't knew about it.

    Could you please back it with some links?

    Thanks!
     
    Jacob, Aug 15, 2005
    #9
  10. Alf P. Steinbach

    Default User Guest

    Greg wrote:

    >
    > Jacob wrote:
    > > It is a common recommendation to use
    > > "static_cast<SomeType> someInstance" instead of the
    > > traditional infamous "(SomeType) someInstance".
    > >
    > > Should I use the same practice for simple types,
    > > i.e. instead of:
    > >
    > > double fraction = (double) n / total;
    > >
    > > should I write this?
    > >
    > > double fraction = static_cast<double>(n) /
    > > static_cast<double>(total);
    > >
    > > I find the traditional version a lot more readable
    > > in this case.
    > >

    >
    > You should avoid casts altogether and write it the C++ way:
    >
    > double fraction = double(n) / double(total);
    >
    > assuming that n and total are both a scalar value type convertible to
    > a double.



    I think that's even worse. It's very difficult to search for those, and
    it's less obvious at a glance that casting is going on.




    Brian
     
    Default User, Aug 15, 2005
    #10
  11. Alf P. Steinbach

    Greg Guest

    Alf P. Steinbach wrote:
    > * Jacob:
    > > Greg wrote:
    > >
    > > > You should avoid casts altogether and write it the C++ way:
    > > >
    > > > double fraction = double(n) / double(total);
    > > >

    >
    > This is not "the C++ way": using C casts is the way of C programmers.
    >
    >
    > > > assuming that n and total are both a scalar value type convertible to a
    > > > double.

    > >
    > > I like this.

    >
    > It's C-style casts, expressed in C++ functional notation.
    >
    > 'T(v)' is equivalent to '(T)v'.
    >
    >
    > > I did search for backing on this syntax
    > > originally but neither S. Meyers nor A. Sutter mentions
    > > it. And my colleges didn't knew about it.
    > >
    > > Could you please back it with some links?

    >
    > §5.2.3/1.
    >


    The expression double(n) is uniquely C++ both syntactically and
    conceptually since it "constructs" the double value by converting n:

    A simple-type-specifier (dcl.type) followed by a parenthesized
    expression-list constructs a value of the specified type given
    the expression list. (5.2.3.1)

    And in fact replacing "double" with the name of a class that has a
    single parameter constuctor would not change the meaning of the
    expression at all - only the type of the value constructed would
    differ. The advantage here is that the syntax for constructing built-in
    types is made compatible with constructing user-defined types - and
    consistency leads to more comprehensible code.

    The funtional notation is far more restrictive than the C style casts.
    It cannot be used to convert pointers - which are far and away the most
    dangerous conversions to undertake. Certainly for doubles, ints, chars
    and the rest of the built in types, using the static_cast notation
    would be slightly ridiculous. There is no polymorphism with the
    built-in types so whatever the statically declared type of a variable
    happens to be, will be its type for all intents and purposes. In light
    of that fact, one might as well use the notation that creates the least
    clutter in the source code, and that looks the most like existing code
    that performs the identical operation for class types.

    Greg
     
    Greg, Aug 15, 2005
    #11
  12. * Greg:
    >
    > The expression double(n) is uniquely C++ both syntactically and
    > conceptually since it "constructs" the double value by converting n:


    Do you by any chance have pointy hair?


    > It cannot be used to convert pointers - which are far and away the most
    > dangerous conversions to undertake.


    int main()
    {
    typedef unsigned char* UcPtr;

    UcPtr p;
    double c;

    p = UcPtr( &c );
    }

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Aug 15, 2005
    #12
  13. Alf P. Steinbach

    benben Guest

    >> But this is EXACTLY why C++ cast operators look this way: they are so
    >> ugly looking to discourage you and alert you from using them. And you can
    >> always pick up all casts using a find in a text editor.

    >
    > So did they really invent this ugly syntax so I
    > shouldn't use casting, or is this just an urban
    > myth?


    That's what Bjarne Stroustrup said in his faq, have a read.

    >
    > I'd guess there are people from academia telling you
    > not to cast ever, but no industry scale C++ system
    > can do without it. And how can I find the fraction of
    > int 10 to int 35 without casting?


    Not to cast ever is unrealistic, indeed. However, knowing the potential
    danger of cast yet leaving casts all over the source is asking for trouble,
    especially during debugging. A better way would be writing a function which
    does the cast for its callers. This way the code becomes more explicit and,
    most importantly, you are localizing some dangereous operations and that'd
    make debugging and maintaining much easier. Now, you would have ended up
    with a bunch of such functions that really are doing the same thing with
    different types; to generalize, and to make code concise, you can use
    template. Now you end up with some function templates that look like the
    following:

    template <typename TypeTo, typename TypeFrom>
    TypeTo my_safe_cast(const TypeFrom& from)
    {
    // localized dangereous casting code...
    }

    apple a = my_safe_cast<orange>(o);

    Which, basically, is what static_cast, dynamic_cast, and reinterpret_cast
    are.

    >
    > And why do I need a syntax so that _Notepad_ can tell
    > me where my casts are? First, I wouldn't categorize
    > code by casts (I don't need a way to find them all),
    > and a _proper_ editor would tell me (if asked) anyway.


    I haven't seen an editor that can effectively tell me where all the C-style
    casts are. This is not for catagorizing code but for maintainance. Again, if
    my program is plagued by overflow/underflow and bit and byte level runtime
    errors I'd be glad to be able to find out all casting, bit operation,
    limits, etc in a couple of seconds.

    > Isn't it so that static_cast (and its cousins) is an
    > aid for the compiler to to proper type checking and
    > that neither the compiler nor the runtime environment
    > can help me when trying to find the fraction of two
    > integers?


    Type casting by itself doesn't have much meaning. You might want to cast a
    double to an int this way and I might want it the other way. Some casting
    operations are quite trivial while others can be quite complex and
    expensive. So there are always different ways to cast from one type to
    another and that's why C++:

    1. provides different cast operators that does a specific job
    2. provides its cast operators as if they are function templates so that
    you can write your own cast operators.

    Having that said, type cast is not the best way for type conversion.
    Whenever possible, it is easier, simpler, and more managable to start with
    copy constructor, assignment overloading, and explicit functions.

    >
    > Thanks!


    No worries!

    Ben
     
    benben, Aug 16, 2005
    #13
  14. Alf P. Steinbach

    Greg Guest

    Alf P. Steinbach wrote:
    > * Greg:
    > >
    > > The expression double(n) is uniquely C++ both syntactically and
    > > conceptually since it "constructs" the double value by converting n:

    >
    > Do you by any chance have pointy hair?
    >
    >
    > > It cannot be used to convert pointers - which are far and away the most
    > > dangerous conversions to undertake.

    >
    > int main()
    > {
    > typedef unsigned char* UcPtr;
    >
    > UcPtr p;
    > double c;
    >
    > p = UcPtr( &c );
    > }


    Granted, it's possible to circumvent the restrictive syntax of this
    method of conversion, but if someone is determined to convert a char
    pointer to a double, I doubt that they would go about it this way.

    The function notation for explicit conversions was added to C++ for a
    reason. It does not exist for backward compatibility with C. There must
    therefore be situations where its use would be a better choice than any
    other conversion operator. And if converting an int to a double is not
    one of those cases, then for what kind of conversion was it meant to be
    used?

    Greg
     
    Greg, Aug 16, 2005
    #14
  15. Alf P. Steinbach

    Old Wolf Guest

    Jacob wrote:
    > Greg wrote:
    >
    >> You should avoid casts altogether and write it the C++ way:
    >>
    >> double fraction = double(n) / double(total);


    Only one of the operands of '/' (or any other arithmetic
    operator) needs to be converted:

    double fraction = double(n) / total;

    Another option would be:
    double fraction = n;
    fraction /= total;

    > I like this. I did search for backing on this syntax
    > originally but neither S. Meyers nor A. Sutter mentions
    > it. And my colleges didn't knew about it.
    >
    > Could you please back it with some links?


    It's called "constructing a temporary object".
    Here is an analogous example, with string
    instead of double:

    string name = string("john") + " doe";

    I fail to see how this is un-C++ as another poster
    claimed; would he prefer to write:
    string name = static_cast<string>("john") + " doe";
    ?

    One reason that constructor syntax can be applied to
    intrinsic types as well as class types is this:

    template<typename A, typename B>
    A sum(B x, B y)
    {
    return A(x) + y;
    }

    // in a function somewhere
    cout << sum<double>(1, -5) << '\n';
    cout << sum<string>("john", " doe") << '\n';
     
    Old Wolf, Aug 16, 2005
    #15
  16. * Greg:
    >
    > Alf P. Steinbach wrote:
    > > * Greg:
    > > >
    > > > The expression double(n) is uniquely C++ both syntactically and
    > > > conceptually since it "constructs" the double value by converting n:

    > >
    > > Do you by any chance have pointy hair?
    > >
    > >
    > > > It cannot be used to convert pointers - which are far and away the most
    > > > dangerous conversions to undertake.

    > >
    > > int main()
    > > {
    > > typedef unsigned char* UcPtr;
    > >
    > > UcPtr p;
    > > double c;
    > >
    > > p = UcPtr( &c );
    > > }

    >
    > Granted, it's possible to circumvent the restrictive syntax of this
    > method of conversion,


    The syntax is not restrictive, quite the opposite, and no circumvention is
    needed.


    > but if someone is determined to convert a char
    > pointer to a double, I doubt that they would go about it this way.


    Do you at all understand that your statement "it cannot be used to convert
    pointers" is incorrect?


    > The function notation for explicit conversions was added to C++ for a
    > reason. It does not exist for backward compatibility with C. There must
    > therefore be situations where its use would be a better choice than any
    > other conversion operator. And if converting an int to a double is not
    > one of those cases, then for what kind of conversion was it meant to be
    > used?


    Do you by any chance have pointy hair?

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Aug 16, 2005
    #16
  17. * Old Wolf:
    >
    > It's called "constructing a temporary object".


    No, in general it's not, because it's equivalent to a C-style cast: the
    standard uses the word equivalent.


    > Here is an analogous example, with string
    > instead of double:
    >
    > string name = string("john") + " doe";
    >
    > I fail to see how this is un-C++ as another poster
    > claimed; would he prefer to write:
    > string name = static_cast<string>("john") + " doe";
    > ?


    The example is not analogous except partially in syntax.

    <url: http://www.nizkor.org/features/fallacies/straw-man.html>.

    When you attack someone's position, be accurate, be truthful, name names,
    and so on.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Aug 16, 2005
    #17
  18. Alf P. Steinbach

    Jacob Guest

    Old Wolf wrote:

    > double fraction = n;
    > fraction /= total;


    This is certainly a way to compute the fraction n/total
    without using casts, but it is conceptually wrong;
    At the instance between the two statements "fraction"
    will be incorrect and represents a pending bug.
     
    Jacob, Aug 18, 2005
    #18
  19. Alf P. Steinbach

    Old Wolf Guest

    Jacob wrote:
    > Old Wolf wrote:
    >
    > > double fraction = n;
    > > fraction /= total;

    >
    > This is certainly a way to compute the fraction n/total
    > without using casts, but it is conceptually wrong;
    > At the instance between the two statements "fraction"
    > will be incorrect and represents a pending bug.


    Huh?

    Are you saying this is bad because someone might
    remove the second statement at a later date?
     
    Old Wolf, Aug 18, 2005
    #19
  20. Alf P. Steinbach

    Old Wolf Guest

    Alf P. Steinbach wrote:
    > * Old Wolf:

    [re. the construction: double(n) ]
    >>
    >> It's called "constructing a temporary object".

    >
    > No, in general it's not, because it's equivalent to a C-style cast: the
    > standard uses the word equivalent.


    Well, constructing a [X] with [Y] as parameter, is equvalent
    to casting [Y] to [X], is it not? Certainly no conforming
    program can tell the difference. You conveniently snipped
    the template example, which I think is a good illustration
    of temporary objects.

    Here's another example:

    double get() { return double(); }

    The return statement creates a temporary double and then
    returns it. No arguments here.

    But you would say that the following does not create a
    temporary double? :

    double get() { return double(1); }
     
    Old Wolf, Aug 18, 2005
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?Q2hyaXMgRGF2b2xp?=

    Web casts in ASP.Net

    =?Utf-8?B?Q2hyaXMgRGF2b2xp?=, Oct 19, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    527
    clintonG
    Oct 19, 2005
  2. cgbusch
    Replies:
    2
    Views:
    348
    Sudsy
    Jul 8, 2003
  3. Joona I Palaste

    Needless casts?

    Joona I Palaste, Apr 24, 2004, in forum: Java
    Replies:
    15
    Views:
    714
    Icemerth
    Apr 25, 2004
  4. Dan Upton

    checking casts

    Dan Upton, Nov 29, 2005, in forum: Java
    Replies:
    4
    Views:
    760
    Chris Smith
    Dec 1, 2005
  5. Wenjie

    C++ casts on zero

    Wenjie, Aug 17, 2003, in forum: C++
    Replies:
    11
    Views:
    689
    Wenjie
    Aug 24, 2003
Loading...

Share This Page