в современном C, учитывая структуру A, если я хочу получить доступ к ее разметке памяти
с структурой макета несвязанной структуры B, как это сделать?
Один не делает это в соответствующей программе.
Из приведенного выше утверждения кажется, что это неопределенное поведение.
Такая операция имеет неопределенное поведение в каждой версии стандарта C. Это не изменилось. Что изменилось, так это свободы, которые некоторые компиляторы могут принять во внимание из-за неопределенности поведения. Лучшая альтернатива - структурировать ваш код так, чтобы вы не проявляли такого поведения в первую очередь.
Предположим, что ваш код демонстрирует такое неопределенное поведение, и вы не хотите его изменять, вы можете рассмотреть объявление типа объединения, содержащего элементы обоих задействованных структурных типов:
union dummy {
struct FooObject foo;
struct PyObject p;
};
В рамках такого объединения компилятор и компилятор , вероятно, сочтут небезопасным предполагать, что указатели на эти типы не дублируют друг друга.
Если вас беспокоит только конкретный компилятор, то вполне возможно, что вы можете вместо этого полагаться на параметр командной строки. Например, в GCC флаг -fno-strict-aliasing
будет глобально отключать оптимизации, которые зависят от предположений о том, что указатели на разные типы не дублируют друг друга.
Но я подчеркиваю, что обе эти альтернативы - обходные пути, а не добросовестные решения.
Добавление:
Однако обратите внимание, что если первый член, объявленный макросом PyObject_HEAD
, имеет тип struct PyObject
, то ваш FooObject
/ PyObject
не соответствует шаблону, о котором вы спрашивали: введите struct FooObject
и struct PyObject
тогда тесно связаны, поскольку FooObject
имеет PyObject
в качестве первого члена.
Если это так, то стандарт гарантирует, что если fp
является указателем на FooObject
, то (PyObject *) fp
является действительным указателем на PyObject
, который является его первым членом. Доступ к первому члену структуры через указатель на его тип, полученный описанным способом, имеет совершенно определенное поведение. Более того, если определение типа struct FooObject
находится в области видимости, и оно объявляет struct PyObject
в качестве своего первого члена, тогда это служит лучше и надежнее, чем объединение, подобное описанному выше.
Ничто из этого не относится к случаю структур, чьи ведущие элементы просто имеют одинаковые типы, в том же порядке, однако, использовал в качестве случая, полученного с использованием PyObject_HEAD
. Весь смысл PEP-3123 состоял в том, чтобы перейти от этого случая к случаю, когда PyObject_HEAD
объявляет (только) сам PyObject
, как только что обсуждалось, а не отдельные члены одного.