2009-09-05 3 views
25

Что такое C-эквивалент для reinterpret_cast от C++?Что такое эквивалент C для reinterpret_cast?

+20

Обратите внимание, что выражение '(type) exression', эквивалентное C, может сделать гораздо больше, чем' reinterpret_cast' в C++ (ну, в конце концов, это два разных языка, поэтому мы не можем ожидать многого). Он может вводить целочисленные и с плавающей точкой типы друг в друга. Не следует из ответов, что выражение '(type)' в C++ эквивалентно 'reinterpret_cast'. –

+0

@litb Это интересный комментарий. Я проверил код сборки, выпущенный VC2008, и он опустил тот же код. Я уверен, что этого недостаточно, но я очень хочу узнать больше, когда он отличается? – AraK

+0

Различные случаи ошибки времени компиляции и неопределенного поведения: 'int a = reinterpret_cast ('a');' (ошибка компиляции). '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; } '(неопределенное поведение: обратите внимание на разницу при изменении на' (B &) c': если под-объект B хранится со смещением '! = 0x0', тогда' reinterpret_cast' не требуется заботиться о любых необходимых настройках , в то время как кастинг в стиле C будет делать. –

ответ

22
int *foo; 
float *bar; 

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

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

Также обратите внимание на то, что в комментарии к исходному вопросу очень хороший момент. – Crashworks

4

C-стиль слепков просто выглядят как имена типов в скобках:

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

Очевидно, что лучшее применение для слепков, чем это, но это основной синтаксис.

+1

Почему «скорее всего» Что будет здесь исключением? – bzeaman

1

C-стиле бросок:

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

не должен, чтобы '==' был единственным знак равно – KPexEA

+0

Оба являются действительными заявлениями, и оба будут скомпилированы только из-за приведения. Конечно, если вы хотите, чтобы что-то произошло иначе, чем компиляция, вы бы использовали '=' – MSalters

0

Вы можете свободно отбрасывать типов указателей в C, как и любой другой тип.

Чтобы быть полным:

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

. Вы можете свободно создавать любой тип, он просто не может делать то, что вы надеетесь, и может не гарантировать что-либо вообще. –

2

Он не существует, потому что reinterpret_cast не может изменить [константность] [3]. Например,

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

произведет ошибку:

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

Если вы можете взять адрес значения, один способ бросить указатель на него, чтобы указатель на другой тип, и затем разыщите указатель.

Например, флоат-к-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); 
} 

Выход:

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

Обратите внимание, что это, вероятно, не гарантируется стандартом C. Вы не можете использовать reinterpret_cast для переноса из float в int в любом случае, но он будет похож на тип, который был поддержан (например, между разными типами указателей).

Подтвердите вывод выше, имеет смысл, во всяком случае.

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

Последний ответ в двоичной системе:

Это IEEE-754 в формате с плавающей точкой: знак бит 0, а затем 8 (011 1111 1), за которым следует 23-битная мантисса (все нули).

Для того, чтобы интерпретировать показатель, вычесть 127: 01111111b = 127, и 127 - 127 = 0. Показатель равен 0.

Для интерпретации мантиссы, записать его после того, как 1 с последующей десятичной точкой: +1,00000000000000000000000 (23 нули). Это 1 в десятичной форме.

Следовательно, значение, представленное hex 3f800000, равно 1 * 2^0 = 1, как мы и ожидали.

0

насчет REINTERPRET оператора с:

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

Я не люблю говорить «reinterpret_cast», потому что бросок означает преобразование (в с), в то время как переинтерпретировать означает обратный: нет преобразования.

+2

Зачем кому-то это делать? Это вводит в заблуждение. Не делайте код незапрошенным. –

Смежные вопросы