Sign in to follow this  
Funso

Casting to avoid warnings

Recommended Posts

Funso    122
I have alot of wanrings in my code. I've got rid of half by getting rid of warnings related to deprecated code. The other half is mostly because of situations where one data type is used in place of another. Now, I know that when I have an int and am passing float data to it, that takes along time due to rounding. So using
int a = (int)thatFloat;
is slow. Am I right, then, in thinking the other casts are ok? For example I have some RECTs I am making for text, and I am getting warnings about passing floats into longs. I should leave those because of rounding, and just suck it up and handle the warning. Is that the best plan? Other times, I am using vectors and I need to know how many objects are in the vector. Am I ok casting from t_size to int because there isn't a slow down? I've always just gone and programmed and never really worried about casting, but this time I want to clear up that darned box of all the warnings I get, and on this occasion speed does matter. Maybe someone could point me towards an article or two on this? It's an interesting topic but google isn't helping me too much.

Share this post


Link to post
Share on other sites
JTippetts    12950
Worrying about the speed of a cast is completely pointless. You should instead worry about why there is a cast in the first place, and what consequences can arise from having it there. Any casting situation can (possibly) result in a loss of data or some other unintended consequence. Casting from float to long, of course, loses decimal precision. Casting from size_t to in can cause an overflow, since size_t is based on an unsigned integer type.

You should evaluate each situation where you receive a casting warning, and determine whether you actually need to cast, or whether you should instead be working with the 'correct' data type. They give you a warning for a reason.

Share this post


Link to post
Share on other sites
phresnel    953
Quote:
Original post by Funso
Now, I know that when I have an int and am passing float data to it, that takes along time due to rounding. So using

int a = (int)thatFloat;

is slow.


The only difference from not casting that float to int explicitly is that you get a warning. The compiler will anyway emit the same casting-code, what else shall he do when you try to assign a float to int? (the alternative would be to throw an error).

And if I remember correctly, since Pentium a x86/87 fistp took no more than 6 cycles.


Sidenote: In clean C++, you use static_cast<target-type>(sourceValue), not (target-type)sourceValue or target-type(sourceValue), for such conversion.

Share this post


Link to post
Share on other sites
frob    44908
It is more than just the fraction truncation. Rounding is generally not a problem.

The warning there is very significant: If the integral part cannot be represented in the destination type, the behavior is undefined.

When storing to a char, there is no check to verify that it fits within CHAR_MIN and CHAR_MAX. No runtime check for INT_MIN and INT_MAX for integers. No runtime check for storing in a signed or unsigned variable of short, long, or any other integral type. If the value at runtime when the conversion takes place doesn't fit, you get undefined behavior.

If you aren't familiar with undefined behavior, it is a Really Bad Thing. It might appear to do nothing wrong. It might happen to do the thing you expected. It might crash every time. It might randomly crash. It might introduce random errors. It might cause toenail fungus and make your pet leave you. It is just a Bad Thing.

The warning is there to help you avoid the significant bug of undefined behavior.

Share this post


Link to post
Share on other sites
AshleysBrain    162
Quote:
Original post by phresnel
And if I remember correctly, since Pentium a x86/87 fistp took no more than 6 cycles.


The fistp instruction is fast, but some compilers don't actually use it for float->int casts. I know that MSVC uses a ftol subroutine for standards compliance which in some situations can bottleneck code using a lot of casts. If you want a non-C++-standard compliant fistp instruction, you have to either use inline assembly or a special compiler switch to generate a fistp instruction for casts (which risks breaking things because it's not standards compliant, and also depends on the FPU rounding mode).

As mentioned, the cast int a = myfloat is an implicit cast, and int a = (int)myfloat is an explicit cast. The compiler issues a warning for implicit casts because it isn't sure that was your intention, whereas typing in a cast explicity shows your intention is to convert the data type. If it is your intention to implicitly cast and you don't care about the side effects, #pragma warning(disable: xxxx) or similar can turn off the warning.

Share this post


Link to post
Share on other sites
kyoryu    224
Quote:
Original post by Funso
I have alot of wanrings in my code. I've got rid of half by getting rid of warnings related to deprecated code. The other half is mostly because of situations where one data type is used in place of another.

Now, I know that when I have an int and am passing float data to it, that takes along time due to rounding. So using

int a = (int)thatFloat;

is slow.


The point of that particular warning isn't due to performance (most compiler warnings aren't), but correctness. When you cast to an int, you are potentially losing data, and have potentially undefined behavior (if the truncated float can't fit in an int).

What the compiler is doing is making sure that you know you're doing this. When you cast to an int, you're telling the compiler, "yes, I'm sure that this is what I want to do."


float a = 2.5f;
float b = 2.5f;
int ai = (int)a;
int bi = (int)b;
float fAnswer = a + b;
int fAnswerToInt = (int) fAnswer;
int intAnswer = ai + bi;


Obviously, fAnswerToInt and intAnswer won't be the same. This loss of data is what the compiler is warning you about.

Share this post


Link to post
Share on other sites
argonaut    100
Quote:
Original post by AshleysBrain
#pragma warning(disable: xxxx) or similar can turn off the warning.


Generally, I would warn (no pun intended) against this sort of thing. Explicitly casting is generally a better way to go, especially once you get into "self commenting" code.

Share this post


Link to post
Share on other sites
Aardvajk    13207
If you are using C++, I'd get out of the habit of using those C-style casts and into the habit of using the C++ explicit casts. Consider:


void f()
{
char *s="hello";

int c=(int)s; // compiles, probably not what you meant to do

int d=(int)23.0f;
}

void g()
{
char *s="hello";

int c1=static_cast<int>(s); // error, probably rightly so
int c2=reinterpret_cast<int>(s); // compiles, tells the compiler you are sure

int d=static_cast<int>(23.0f); // compiles
}


Using static_cast will cause compiler errors where there is no implicit conversion between the types. When you really need to do a reinterpretation of the bits from one type to another, reinterpret_cast makes it explicit in your code that this is your intention.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this