http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
В качестве дополнения к принятому ответу, вот полная цитата из стандарта, в которой выделена важная часть, в которой пропущен другой ответ, и еще один:
6.7.2.1-13: Внутри структурного объекта члены, не являющиеся битовыми полями, и блоки, в которых находятся битовые поля, имеют адреса, возрастающие в порядке их объявления. Указатель на объект структуры, соответствующим образом преобразованный, указывает на его начальный элемент (или, если этот элемент является битовым полем, то на модуль, в котором он находится), и наоборот. Внутри объекта структуры может быть безымянный отступ, но не в его начале.
6.3.2.3-7: Указатель на объект или неполный тип может быть преобразован в указатель на другой объект или неполный тип. Если результирующий указатель неправильно выровнен для указанного типа, поведение не определено. В противном случае при обратном преобразовании результат будет равен исходному указателю. [...]
Я считаю ваш пример идеальным местом для указателя void:
int age(void *object) {
Почему? Потому что ваше очевидное намерение состоит в том, чтобы дать такой функции разные типы объектов, и она получает информацию в соответствии с закодированным типом. В вашей версии вам нужно приводить каждый раз, когда вы вызываете функцию: age((object_t*)person);
. Компилятор не будет жаловаться, если вы дадите ему неправильный указатель, так что в любом случае безопасность типов не задействована. Затем вы также можете использовать указатель void и избегать приведения при вызове функции.
В качестве альтернативы вы можете, конечно, вызвать функцию с помощью age(&person->object)
. Каждый раз, когда вы звоните.
person
Secure
schedule
07.12.2011
int type
, чтобы проверить тип, а затем правильно привести его. - person Joe   schedule 07.12.2011object_t
не имеет ничего общего сperson_t
? - person duedl0r   schedule 07.12.2011person_t*
какobject_t*
, а наоборот. И этот другой путь небезопасен даже с проверкой наtype
, потому что его можно обмануть. - person mouviciel   schedule 07.12.2011person_t
включаетobject_t
: использование псевдонимов разрешено.object_t
не включаетperson_t
: псевдонимы не разрешены. - person mouviciel   schedule 07.12.2011