Jump to content

  • Log In with Google      Sign In   
  • Create Account

casting an expression: what exactly casts the compiler?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
6 replies to this topic

#1 Alessio1989   Members   -  Reputation: 2008

Like
0Likes
Like

Posted 24 February 2014 - 12:01 PM

If I cast an expression with C++ casts, or even C-style casts, what exactly will cast the compiler?

 

Does the compiler cast every symbol of the expression before evaluating it or does it cast only the final expression value without casting the expression symbols?

 

eg: if I want cast only the final result of the expression without changing the symbols type, do I need to cast every symbol of the expression of its own type and then cast the entire expression to the target type or I don't need to do that?


Edited by Alessio1989, 24 February 2014 - 12:04 PM.

"Software does not run in a magical fairy aether powered by the fevered dreams of CS PhDs"


Sponsor:

#2 SimonForsman   Crossbones+   -  Reputation: 6111

Like
0Likes
Like

Posted 24 February 2014 - 12:16 PM

it should only cast the result afaik.


I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!

#3 nobodynews   Crossbones+   -  Reputation: 1916

Like
0Likes
Like

Posted 24 February 2014 - 01:13 PM

When you do the cast only the result of the expression contained within the cast is casted. However, the compiler automatically casts certain things within an expression. For example, if you multiply a float variable by an integer variable the integer will be casted to a float causing the operation to be float * float. I believe most/all of these conversions are well-defined by the standard, but can't say for sure. There might be some confusing unsigned/signed casting quirks that are unspecified or undefined.

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!


#4 RobTheBloke   Crossbones+   -  Reputation: 2342

Like
1Likes
Like

Posted 24 February 2014 - 01:23 PM

it should only cast the result afaik.

 

I hope not! It should cast whatever is directly in front of the cast operator. So, in this case:


int a=1, b = 2;
float f = (float)a/b;
 

It will convert both a and b to floats prior to computing the division. The cast itself will only actually force 'a' to be converted to a float, but since 'a' is a float, 'b' will in turn be converted to a float (due to the rule that the operand on the left of the operator determining the operation used). As proof, the ASM looks like this:

 
cvtsi2ss xmm0, DWORD PTR _a$[ebp] // convert a to float
cvtsi2ss xmm1, DWORD PTR _b$[ebp] // convert b to float
divss<span> </span>xmm0, xmm1
movss<span> </span>DWORD PTR _c$[ebp], xmm0
 
In this case however, it will evaluate a/b using integers, and then cast the result.


int a=1, b = 2;
float f = (float)(a / b);
 
The ASM: 
 
</span>

mov<span> </span>eax, DWORD PTR _a$[ebp]
cdq
idiv<span> </span>DWORD PTR _b$[ebp] // integer division
cvtsi2ss xmm0, eax // convert result to float
movss<span> </span>DWORD PTR _d$[ebp], xmm0



#5 frob   Moderators   -  Reputation: 21323

Like
5Likes
Like

Posted 24 February 2014 - 01:26 PM

The language standards specify a bunch of conversions that can happen automatically, called "implicit conversions", and provide the rules for when they happen and why a specific one is triggered. In C++ you can also write conversion operators in your class that might trigger those rules as well.

As for what happens on the actual processor, that is mostly up to the compiler. Some conversions have no effect on the data stored on a register, such as re-interpreting an 'int' to a 'long' on a 32-bit system, or casting a pointer from one type to another on a system with uniform flat memory. Some conversions have hidden function calls or move data from one place to another, or one format to another.
Check out my personal indie blog at bryanwagstaff.com.

#6 Alessio1989   Members   -  Reputation: 2008

Like
0Likes
Like

Posted 24 February 2014 - 01:50 PM

Thank you everyone for the answers.


"Software does not run in a magical fairy aether powered by the fevered dreams of CS PhDs"


#7 SeanMiddleditch   Members   -  Reputation: 5868

Like
1Likes
Like

Posted 24 February 2014 - 03:44 PM

due to the rule that the operand on the left of the operator determining the operation used


There is no such rule.

Each operand is equal in its consideration of which operator overload to invoke or which implicit conversion to perform. The following would also have an implicit cast to float:
 
int a; float b;
auto c = a / b; // decltype(c) ==> float
Implicit conversions have a (relatively) complex set of rules about what can be cast to what and when. Which side of an operator each operand on is not a part of those rules.

With user-defined types nothing stops you from overloading operators with operands in whatever order you choose, so long as at least one operand is a user-defined type:
 
struct A {};
A operator/(A l, float r);
A operator/(float l, A r);





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS