Do I need a typecast here?

M

mike3

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((fracObtained < 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 "fracObtained" 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?
 
A

Andrey Tarasevich

mike3 said:
I heard that in C++ typecasts are "evil".
>

Even if someone says that typecasts are "evil", they are normally
referring to the conversions of class types along the class hierarchy.
While even that is questionable, it is not relevant to your case. In
your case you are thinking about simple arithmetical typecast. This is a
completely different thing. There's absolutely nothing "evil" about
arithmetical typecasts. If you need one, then you need one. Although in
some cases a solution without typecast might prove to be more elegant
than one with a typecast. On the second thought, the reverse is also
possible.
 
M

mike3

Even if someone says that typecasts are "evil", they are normally
referring to the conversions of class types along the class hierarchy.
While even that is questionable, it is not relevant to your case. In
your case you are thinking about simple arithmetical typecast. This is a
completely different thing. There's absolutely nothing "evil" about
arithmetical typecasts. If you need one, then you need one. Although in
some cases a solution without typecast might prove to be more elegant
than one with a typecast. On the second thought, the reverse is also
possible.

Thanks for the answer.
 
J

James Kanze

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((fracObtained < 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 "fracObtained" 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.)
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top