Do I need a typecast here?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • mike3

    Do I need a typecast here?

    Hi.

    I heard that in C++ typecasts are "evil". However, what does one do
    with this thing?:

    ---
    /* Figure out how many digits of fraction we'll get.
    * We add 1 to the lengths of a and b to take into account
    * the hidden bits.
    */
    int fracObtained((( aLength + 1) - (bLength + 1)));
    std::size_t bufExtra(0);
    if((fracObtaine d < rLength) || (fracObtained < MIN_PRECISION))
    <---- yuck :(
    {
    /* We need more */
    bufExtra = rLength - fracObtained;
    }
    ---

    But if I simply do

    ---
    /* Figure out how many digits of fraction we'll get.
    * We add 1 to the lengths of a and b to take into account
    * the hidden bits.
    */
    int fracObtained((( aLength + 1) - (bLength + 1)));
    std::size_t bufExtra(0);
    if(fracObtained < rLength) <--- nice :) but doesn't work due to
    signed/unsigned comparison :(
    {
    /* We need more */
    bufExtra = rLength - fracObtained;
    }
    ---

    it fails when "fracObtain ed" is negative, because rLength is also of
    type std::size_t, which
    is an unsigned type. The former code uses no typecast, the latter
    doesn't either, but the
    former works however it having that goofy extra check in there may be
    confusing while
    the latter, simply comparing it to rLength seems clearer and more
    natural. But for the latter to work,
    you need a typecast of rLength to int. But is the "evil" here
    necessary if one wants to
    write good code for this?
  • James Kanze

    #2
    Re: Do I need a typecast here?

    On Feb 27, 10:44 pm, mike3 <mike4...@yahoo .comwrote:
    I heard that in C++ typecasts are "evil".
    Sometimes a necessary evil. And even...
    However, what does one do with this thing?:
    ---
    /* Figure out how many digits of fraction we'll get.
    * We add 1 to the lengths of a and b to take into account
    * the hidden bits.
    */
    int fracObtained((( aLength + 1) - (bLength + 1)));
    std::size_t bufExtra(0);
    if((fracObtaine d < rLength) || (fracObtained < MIN_PRECISION))
    <---- yuck :(
    {
    /* We need more */
    bufExtra = rLength - fracObtained;
    }
    ---
    But if I simply do
    ---
    /* Figure out how many digits of fraction we'll get.
    * We add 1 to the lengths of a and b to take into account
    * the hidden bits.
    */
    int fracObtained((( aLength + 1) - (bLength + 1)));
    std::size_t bufExtra(0);
    if(fracObtained < rLength) <--- nice :) but doesn't work due to
    signed/unsigned comparison :(
    {
    /* We need more */
    bufExtra = rLength - fracObtained;
    }
    ---
    it fails when "fracObtain ed" is negative, because rLength is
    also of type std::size_t, which is an unsigned type.
    Comparing a signed integral type with an unsigned is evil in
    C++. There will be an implicit conversion, but not necessarily
    in the way you want.
    The former code uses no typecast, the latter doesn't either,
    but the former works however it having that goofy extra check
    in there may be confusing while the latter, simply comparing
    it to rLength seems clearer and more natural.
    >But for the latter to work, you need a typecast of rLength to
    >int. But is the "evil" here necessary if one wants to write
    >good code for this?
    The evil is that you're mixing signed and unsigned integral
    types:-). Depending on what you are doing, it may be an
    unavoidable evil---you can't change the type of sizeof, and you
    can't change the types returned by std::vector<>:: size() and
    others. If you can't avoid mixing signed and unsigned, then
    telling the compiler (and the reader) explicity which way you
    want the conversions to be done is good. (In many ways,
    implicit conversions are even more evil than casts. But again,
    it depends on the context.)

    Of course, if there are no other constraints, the "correct"
    solution is to make rLength an int. (In C++, int is the
    default integral type, and should always be used for integral
    values unless there is some constraint which makes it
    impossible, or at least unreasonable.)

    --
    James Kanze (GABI Software) email:james.kan ze@gmail.com
    Conseils en informatique orientée objet/
    Beratung in objektorientier ter Datenverarbeitu ng
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

    Comment

    Working...