Is primitive casting creating a new object in memory?

My question is simple if in C ++ there is the following code:

int main(int argc, const char * argv[]) { int i1 = 5; int i2 = 2; float f = i1/(float)i2; std::cout << f << "\n"; return 0; } 

Is (float)i2 to create a new object in memory that is going to split i1 and assigned to f , or does the casting operator somehow translate (float)i2 on the fly and do the division without additional memory for casting?

Also, what happens to cases where casting requires different sizes of variables? (e.g. float to double)

+5
source share
3 answers

Is (float)i2 to create a new object in memory

The cast creates a temporary object that will have its own storage. It is not necessary in memory; such a small arithmetic value is likely to be created and used in the register.

Also, what happens to cases where casting requires different sizes of variables?

Since a new object is created, it does not matter if they have a different size and representation.

+4
source

It depends on the implementation of the compiler and the architecture of the machine. The compiler can use processor registers for temporary variables, and if necessary, it can use the memory stack. Examining the output at the assembly level of the compiler will tell you what it does in a particular case.

+1
source

The conversion value can be stored in memory or in a register. It depends on your hardware and compiler and compilation capabilities. Consider the result of compiling your fragment using g++ -O0 -c -g cast_code.cpp on 64-bit gg cygwin:

  [...] 14: c7 45 fc 05 00 00 00 movl $0x5,-0x4(%rbp) int i2 = 2; 1b: c7 45 f8 02 00 00 00 movl $0x2,-0x8(%rbp) float f = i1/(float)i2; 22: f3 0f 2a 45 fc cvtsi2ssl -0x4(%rbp),%xmm0 27: f3 0f 2a 4d f8 cvtsi2ssl -0x8(%rbp),%xmm1 2c: f3 0f 5e c1 divss %xmm1,%xmm0 30: f3 0f 11 45 f4 movss %xmm0,-0xc(%rbp) [...] 

. Ints are pushed onto the stack and then converted to floats, which are stored in the mmx register. New objects? Debatable; in memory: probably not (depending on what memory is, memory should be addressable to me).

If we instruct the compiler to store variables correctly (for example, to avoid problems with points with more accurate registers), we get the following:

g++ -O0 -c -g -ffloat-store cast_code.cpp results in

  // identical to above 14: c7 45 fc 05 00 00 00 movl $0x5,-0x4(%rbp) int i2 = 2; 1b: c7 45 f8 02 00 00 00 movl $0x2,-0x8(%rbp) float f = i1/(float)i2; // same conversion 22: f3 0f 2a 45 fc cvtsi2ssl -0x4(%rbp),%xmm0 // but then the result is stored on the stack. 27: f3 0f 11 45 f4 movss %xmm0,-0xc(%rbp) // same for the second value (which undergoes an implicit conversion). 2c: f3 0f 2a 45 f8 cvtsi2ssl -0x8(%rbp),%xmm0 31: f3 0f 11 45 f0 movss %xmm0,-0x10(%rbp) 36: f3 0f 10 45 f4 movss -0xc(%rbp),%xmm0 3b: f3 0f 5e 45 f0 divss -0x10(%rbp),%xmm0 40: f3 0f 11 45 ec movss %xmm0,-0x14(%rbp) 

It’s a little painful to see how i1 moves from register to memory at 27, and then back to register at 36, so division can be done at level 3b.

Anyway, hope this helps.

+1
source

Source: https://habr.com/ru/post/1201818/


All Articles