2009-09-05 12 views
25

Co to jest ekwiwalent C dla reinterpret_cast z C++?Jaki jest ekwiwalent C dla reinterpret_cast?

+20

Zauważ, że ekwiwalent C dla '' (type) 'może znacznie więcej niż" reinterpretować "w C++ (cóż, w końcu są to dwa różne języki - więc i tak nie możemy się wiele spodziewać). Może rzutować na siebie typy liczb całkowitych i zmiennoprzecinkowych. Nie wyciągaj wniosków z odpowiedzi, że '(typ) wyrażenie' w C++ jest równoważne' reinterpret_cast'. –

+0

@litb To jest ciekawy komentarz. Sprawdziłem kod produkowany przez VC2008 i pomija ten sam kod. Jestem pewien, że to nie wystarczy, ale naprawdę chcę wiedzieć więcej, kiedy to się różni? – AraK

+0

Odmienne przypadki błędu czasu kompilacji i niezdefiniowanego zachowania: 'int a = reinterpret_cast (" a ");' (błąd kompilacji). 'struct A {int a; }; struct B {int b; }; struct C: A, B {int c; }; int main() {C c; B & b = reinterpret_cast (c); b.b = 1; } '(niezdefiniowane zachowanie: zauważ różnicę po zmianie na' (B &) c': jeśli obiekt podrzędny B jest przechowywany z przesunięciem '! = 0x0', to' reinterpret_cast' nie jest wymagane, aby zadbać o wszelkie niezbędne korekty , podczas gdy odleje w stylu C. –

Odpowiedz

22
int *foo; 
float *bar; 

// c++ style: 
foo = reinterpret_cast< int * >(bar); 

// c style: 
foo = (int *)(bar); 
+4

Proszę również zwrócić uwagę na bardzo dobry punkt litb w komentarzach do pierwotnego pytania. – Crashworks

4

C-styl odlewy prostu wyglądać nazw typów w nawiasie:

void *p = NULL; 
int i = (int)p; // now i is most likely 0 

Oczywiście istnieją lepsze zastosowania dla odlewów niż ten, ale to składnia podstawowe.

+1

Dlaczego "najprawdopodobniej" "Jaki byłby tutaj wyjątek? – bzeaman

1

A C-style cast jest:

int* two = ...; 
pointerToOne* one = (pointerToOne*)two; 
+0

nie powinno to oznaczać, że" == " "=" "? – KPexEA

+0

Obie są poprawnymi instrukcjami, a obie będą kompilowane tylko z powodu obsady. Oczywiście, jeśli chcesz coś innego niż kompilowanie, możesz użyć "=" – MSalters

0

Można swobodnie rzucać rodzajów wskaźnik w C tak samo jak każdy inny rodzaj.

Aby być pełne

void *foo; 
some_custom_t *bar; 
other_custom_t *baz; 
/* Initialization... */ 
foo = (void *)bar; 
bar = (some_custom_t *)baz; 
baz = (other_custom_t *)foo; 
+4

Możesz dowolnie rzutować dowolny typ, może po prostu nie robić tego, co masz nadzieję, i nie można zagwarantować, że cokolwiek zrobisz. –

2

nie istnieje, ponieważ nie można zmienić reinterpret_cast [constness] [3]. Na przykład,

int main() 
{ 
    const unsigned int d = 5; 
    int *g=reinterpret_cast< int* >(&d); 
    (void)g; 
} 

będzie produkować błąd:

dk.cpp: In function 'int main()':
dk.cpp:5:41: error: reinterpret_cast from type 'const unsigned int*' to type 'int*' casts away qualifiers

1

Jeśli można wziąć adres wartości, jednym ze sposobów jest do oddania wskaźnik do niego do wskaźnika do innego typu, a następnie usuń zaznaczenie wskaźnika.

Na przykład konwersja pływaka do int:

int main() 
{ 
    float f = 1.0f; 

    printf ("f is %f\n", f); 
    printf ("(int) f is %d\n", (int)f); 
    printf ("f as an unsigned int:%x\n", *(unsigned int *)&f); 
} 

wyjściowa:

f is 1.000000 
(int) f is 1 
f as an unsigned int:3f800000 

Należy pamiętać, że jest to prawdopodobnie nie jest gwarantowana do pracy w standardzie C. Nie można użyć reinterpret_cast do rzutowania z float na int mimo to, ale byłby podobny do typu, który był obsługiwany (na przykład między różnymi typami wskaźników).

Załóżmy, że powyższe wyjście ma sens.

http://en.wikipedia.org/wiki/Single_precision_floating-point_format#IEEE_754_single-precision_binary_floating-point_format:_binary32

Ostatnia odpowiedź w systemie binarnym:

Jest IEEE-754 pływający Format punkt nieco znakiem 0, po którym następuje 8 -bit exponent (011 1111 1), a następnie 23-bitowa mantysa (wszystkie zera).

Aby zinterpretować wykładnik odjąć 127: 01111111b = 127, i 127 - 127 = 0. wykładnikiem 0.

Aby zinterpretować mantysę napisać to po 1 a następnie po przecinku dziesiętnym: +1,00000000000000000000000 (23 zer). Jest to 1 w systemie dziesiętnym.

W związku z tym wartość reprezentowana przez heks 3f800000 wynosi 1 * 2^0 = 1, zgodnie z naszymi oczekiwaniami.

0

Co o REINTERPRET operatora dla C:

#define REINTERPRET(new_type, var) (* ((new_type *) & var)) 

nie lubią mówić „reinterpret_cast”, ponieważ obsada oznacza konwersję (w C), natomiast reinterpretacji oznacza przeciwieństwo: brak konwersji.

+2

Dlaczego ktoś powinien to zrobić? To wprowadza w błąd. Nie twórz nieskomunikowanego kodu. –

Powiązane problemy