2013-11-23 2 views
2
Структуры

При компиляции следующего кода:Cast между двумя эквивалентными C

struct Point { 
    int x; 
    int y; 
}; 
struct Position { 
    int x; 
    int y; 
}; 
struct Point p = {1, 2}; 
struct Position q = (struct Position)p; 

ошибка происходит:

error: used type 'struct Position' where arithmetic or pointer type is required

Не существует какой-то способ бросить между различными struct случаях, когда те, на самом деле имеют struct такое же определение?

+1

Повсеместно указатели: структура Должности * д = (структура Амплуа *) и р; – Shaggi

+1

@Shaggi, в то время как это «работает», это не будет отличаться * экземпляры *. Разнообразность и правильная lvalue сделают то, что ищет OP (не комментируйте, является ли это хорошей идеей). – WhozCraig

+0

@WhozCraig Да, вы правы, ему нужны разные экземпляры :) просто переместите звездочку, как показано в других ответах ... – Shaggi

ответ

3

Нет такой вещи, как «литье» для типов структур на языке C. Язык C поддерживает только роли для скалярных типов и void.

Если какой-либо другой тип используется внутри (), он больше не является отличным. Он может быть действителен только как часть составной литерал синтаксис. Компонентные литералы - это совершенно другая особенность языка C, не связанная с кастами. Например, это было бы правильно

struct Position q = (struct Position) { 1, 2 }; 

В вашем случае, видимо, нужна последовательность reinterperting

q = *(struct Position *) &p; 

языка C заявляет, что этот вид доступа считается действительным до тех пор, пока ваши объявления структур действительно синхронизированы. Вы можете также рассмотреть просто memcpy -в один объект другому.

3

Вы можете сделать это с помощью типа каламбуров, так как стандартные разрешения, что разделяющие две структур общей исходной последовательности псевдонимов, пока только общие начальные элементы доступны:

struct Position q = *(struct Position *)&p; 

или даже лучше

union { 
    struct Position pos; 
    struct Point pt; 
} pun; 

pun.pt = p; 
struct Position q = pun.pos; 
+0

Я заблаговременно проголосую, если вы можете напомнить мне, что разрешено * использовать член союза, который был * не * последним назначенным значением lvalue как выражение rvalue. Мой мозг находится в состоянии блокировки, так как мой последний рабочий проект, наконец, отправлен, так что простите меня, если я сползаю, или если это ограничение находится на C++, а не C. – WhozCraig

+0

@WhozCraig Точно, это ограничение C++. C99 (а не C89, хотя) явно разрешает использование пуна через объединения. –

+0

Спасибо. Мне нравится второй фрагмент только для творческого нюанса, если это так. – WhozCraig

1

Casting one C structure into another

Я думаю, что это есть ответ.

Проверить это также

Is it possible to cast struct to another?

Хотя вы можете бросить почти все к чему-либо, делая это с структурами ошибок.

Вы можете использовать указатель для создания типа;

Point_var = * ((point *) & position_var);

0

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

struct Point *p; 
p->x=1; 
p->y=2; 
struct Position *q = (Position *)p; 
+2

обратите внимание, что - как написано - это неопределенное поведение и, скорее всего, сбой, потому что вы разыскиваете неинициализированный указатель. – user4815162342

+1

Помимо неопределенного поведения путем разыменования неопределенного указателя, это не разные экземпляры, скорее это псевдоним указателя на * тот же * экземпляр. – WhozCraig

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