В C89, если две или более структуры начинаются с элементов совпадающих типов в порядке совпадения (они имеют общую начальную последовательность), и оба являются частью одного и того же объединения, любая часть Common Initial Sequence может быть проверена с использованием соответствующих именованных членов любого типа, разделяющих СНГ. В вашем примере не используются соответствующие типы, поэтому он не подходит, но если он будет использовать соответствующие типы в порядке совпадения, это будет. Насколько я могу судить, компиляторы C89 в 1990-х годах единогласно применяли тот же принцип с указателями на структуры (поэтому, если у структурных типов S1 и S2 есть СНГ, указатель любого типа можно было бы использовать для доступа к членам СНГ). Хотя в Стандарте явно не указано такое обращение, самым простым способом для компилятора обеспечить, чтобы правило применялось во всех случаях с участием профсоюзов, было заставить его применять во всех случаях также и указатели, и многие люди (вероятно, в том числе авторы Стандарта) ожидали, что составители, естественно, сделают это, явно или нет.
C99 требует, чтобы, если код будет использовать указатель одного типа структуры для , для доступа к члену СНГ другого, должно быть видно полное определение типа объединения, чтобы компилятор знал о потенциальном сглаживании между типы. К сожалению, хотя это правило имеет ясную и очевидную цель (позволяя программистам использовать правило CIS, позволяя компиляторам предполагать, что доступ к совершенно несвязанным структурам не будет псевдонимом), некоторые авторы компилятора предполагают, что никакой указатель типа структуры не будет использоваться для доступа к любому другому, даже если объявление полного типа объединения, содержащее оба типа, видимо и даже в тех случаях, когда структуры являются, фактически, членами одного и того же объекта объединения.
Если вы хотите использовать правило Common Initial Sequence, может быть необходимо использовать флаг -fno-strict-aliasing
при использовании компиляторов, у которых есть один (даже если он не использует CIS, используя флаг, может обеспечить защиту от ошибок компилятора). Код, который использует aliasing, должен стремиться сделать его очевидным для компилятора (например, чтобы убедиться, что тип подходящего профсоюза виден), но до тех пор, пока разработчики компилятора не начнут обращать внимание на такие вещи, -fno-strict-aliasing
будет необходим для их неспособности сделать это.
, что это слишком плохо, вы исключили макросы. это лучшее решение здесь. –
@ Jean-FrançoisFabre Я исключил их из-за того, что предположил, что они не полезны для решений времени исполнения.? –
Вся разница между функциями заключается в смещениях членов внутри структур, поэтому код в 'somefunc2()' сильно отличается от кода в 'somefunc1()', а в 'somefunc3()' другой от обеих других функций. Если вы действительно хотите, чтобы одна из трех функций выполняла работу трех, вам нужно написать код, использующий макрос 'offsetof' от'', а задействованные структуры данных будут намного больше, чем повторение minuscule в показанном коде , –