If the cast in C style (float)i; or float(i); , then in essence in both cases the constructor is called and a temporary object is created? But what about pointers, if you cast int* p to (float*)p , then why can't you write float*(p) and what happens with (float*)p ?

UPD:

@VladD ; For static_cast , something is not clear. For example, there is a C style:

 char* str = "123456789"; int* pi = (int*)str; 

and with static_cast will be:

 char* str = "123456789"; void* pv = static_cast<void*>(str); int* pi = static_cast<int*>(pv); 

so why should I bring in, and not immediately to int ?
Is this an intermediate cast made because in C there are no restrictions in terms of assigning a pointer of one type to a pointer of another type, but in C ++ is there? That is, it turns out that if you write in C ++ (int*)str , then it will be decomposed into static_cast<void*> and static_cast<int*> ? And how does reinterpret_cast then ignore this restriction in C ++? Or does it also use static_cast ?

 char* str = "123456789"; int* pi = reinterpret_cast<int*>(str); 

@avp , I understand that this will not work in C:

 int a; float b = float(a); 

because in C there are no classes and the constructor will not be called, but in the constructor it is implicitly reduced. But how then does this work in C:

 int a; float b = (float)a; 

because if in C ++ with (float) a; static_cast or const_cast or reinterpret_cast is selected, what happens in C when (float)a ?

  • one
    Here is a detailed analysis: stackoverflow.com/a/1255015/276994 - VladD
  • one
    @strol, if you can add code fragments describing the types of source and receiver to your question and specify where it’s about C, and where it’s about C ++. - avp
  • Here's more details: * const_cast * static_cast * reinterpret_cast * dynamic_cast * C-style cast - VladD
  • @strol, C is easy. For such a function: extern void f2 (float); void f (int pa) {static int a; a = * pa; float b = a; f2 (b); } on x64 (Intel I5-2500) GCC: (Ubuntu / Linaro 4.6.3-1ubuntu5) 4.6.3 generates these commands: .cfi_startproc movl (% rdi),% eax cvtsi2ss% eax,% xmm0 movl% eax, a .1589 (% rip) jmp f2 .cfi_endproc As you can see, it is to convert int to float one * machine instruction cvtsi2ss is used . In C ++ it will be the same. - avp

1 answer 1

Actually, type casting is a huge topic, it is dumped into one heap and conversions between arithmetic types (expansion / contraction of various types of integer, conversion between whole and floating point and back), and moving up / down the inheritance hierarchy through pointers, and dynamic control of runtime types, and adding / removing const / volatile , everything. All the rules cover - the topic for the section with research.

I will duplicate links to the documentation:


Concerning your question on const_cast : see.

You cannot make a static_cast from char* to int* according to the rules listed here . Rules 1 and 5 could be the most appropriate, but since there is no implicit conversion between char* and int* ( char and int are not subclasses of each other), direct static_cast not possible.

On the other hand, static_cast from char* to void* is possible by rule 1, since there is an implicit conversion from any pointer to data in void* . Reverse conversion from void* to int* is possible by rule 10.

A natural question arises, why do we need such restrictions? The point is this. Direct conversion is prohibited, because using the resulting pointer differently than to convert it back to char* , you do not have the right to the standard. This is due to the so-called strict aliasing rule . It is best to read a detailed explanation with reasons here , in brief: if the pointer points to a char , you cannot contact int 'at this address. [The only exception is conversion to char* .]

Therefore, the language protects you from an error: if you already wrote static_cast twice through void* , you should understand that you are doing something special.

In contrast, the C-style cast is a much more messy thing: the compiler tries const_cast , static_cast , static_cast + const_cast , reinterpret_cast , reinterpret_cast + const_cast , and takes the first thing that fits. This behavior is more typical for languages ​​like Visual Basic: you do not control what is happening, you say to the compiler "in short, decide for me."


C-style cast in C is the only existing type of explicit type conversion. Since it does not have the semantics of inheritance, in it all the conversion operations of pointers are essentially empty, and simply change the look of the compiler at the data at a given address. (Generally, roughly speaking, C works with bytes, and C ++ works with abstract entities.) However, strict alisaing rule works in C.


Note that in C ++ conversion of the pointer between the base and derived types can lead to a change of address - unlike C. This means that reinterpret_cast can give the wrong result, even if static_cast gives the right one! That is, you can not mindlessly use reinterpret_cast in the hope that he will do everything correctly. And it also explains why the C-style cast doesn't boil down to reinterpret_cast .