Посторонний (void *) в: type_a sample; type_b * sample_b = (type_b *) ((void *) & sample); - PullRequest
2 голосов
/ 23 июля 2011

Я читал эту ветку: Переопределение типов с другим typedef

type_b *sample_b = (type_b *) ((void *) &sample);

Не является ли (пустым) посторонним? & sample вернет указатель типа: type_a, который может быть приведен непосредственно к (type_b *). Почему дополнительный (недействительный *)? Я чувствую, что это неправильно, но недостаточно уверен в своем С - отсюда и дополнительная проверка.

Ответы [ 2 ]

2 голосов
/ 23 июля 2011

GCC имеет возможность оптимизировать код на основе того факта, что он обнаруживает, что два указателя, которые указывают на несовместимые типы, указывают на одну и ту же область памяти. Использование обоих указателей для доступа к значению выдаст предупреждение о нарушении псевдонимов («type punning»).

Иногда, если вы поместите (void*) приведение между одним операндом приведения, перед приведением к другому типу точки, отключит ложные положительные предупреждения в случаях, когда вы можете легально сделать такой перекрывающийся доступ ,

0 голосов
/ 23 июля 2011

Приведение указателя к типу void скрывает истинный тип указателя от компилятора, так что вы можете привести его к любому другому типу, который вам нужен, и у компилятора не будет достаточно информации, чтобы знать, действителен ли он или нет, таким образом, это позволит это.

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

ВАЖНОЕ ПРИМЕЧАНИЕ:

Оригинальный постер вопроса, на который вы ссылались, пытается сделать что-то опасное. Предполагается, что выравнивание структур в памяти будет одинаковым, что позволит им получить доступ к двум отдельным символам, как если бы они были одним массивом из двух символов. Это может быть правдой в теории и, вероятно, будет работать в небольшой тестовой программе, но если это будет сделано в части производственного кода, это обязательно закончится слезами и скрежетом зубов в 3 часа ночи. ∗1011*

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