C11 - преобразовать указатель на структуру в анонимный первый член структуры

Стандарт C гласит:

Указатель на объект структуры, соответствующим образом приведенный, указывает на его начальный элемент (или, если этот элемент является битовым полем, то на модуль, в котором он находится), и наоборот.

Есть ли какой-либо возможный (и четко определенный) способ выполнить такое "подходящее приведение" в C11, если первым членом рассматриваемой структуры является анонимная структура / объединение? Или выполнить обратное приведение "наоборот", если содержащая структура является анонимной?

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

Тем не менее, стандарт C гласит:

Кроме того, два типа структуры, объединения или перечисления, объявленные в отдельных единицах перевода, совместимы, если их теги и члены удовлетворяют следующим требованиям: если один объявлен с тегом, другой должен быть объявлен с тем же тегом. Если оба выполняются где-либо в пределах их соответствующих единиц перевода, то применяются следующие дополнительные требования: между их членами должна быть индивидуальная переписка <...>

Можем ли мы попытаться применить это правило к анонимным структурам? Скажем, если у нас есть следующие настройки:

header.h:

struct container {
    struct {
        int a;
        char b;
    };
};

void print(struct container *pcontainer);

sep.c:

#include <stdio.h>
#include "header.h"

void print(struct container *pcontainer){
    printf("%d\n", ((struct { int a; char b; }*)pcontainer)->a);
}

main.c:

#include "header.h"

int main(void){
    struct container container, *pcontainer;

    pcontainer = &container;
    pcontainer->a = 1;

    print(pcontainer);

    return 0;
}

(это компилируется в gcc (GCC) 4.8.3 20140911 и выводит 1).

Рассмотрим анонимную структуру, используемую в приведении внутри print функция и анонимная структура, которая является первым членом struct container что заканчиваетсяmain.c, Могут ли они считаться "типами, объявленными в отдельных единицах перевода"? Кроме того, они действительно удовлетворяют всем другим требованиям совместимости, или я что-то неправильно понимаю?

1 ответ

Что такое переводческая единица:

5.1.1.1 Структура программы

  1. Программу A C не нужно переводить одновременно. Текст программы хранится в единицах, называемых исходными файлами (или файлами предварительной обработки) в этом международном стандарте. Исходный файл вместе со всеми заголовками и исходными файлами, включенными в директиву предварительной обработки #include, называется модулем преобразования предварительной обработки. После предварительной обработки блок преобразования предварительной обработки называется блоком перевода.

Таким образом, c-файл плюс заголовки после предварительной обработки образуют единое целое перевода. Давайте возьмем модуль перевода, который состоит из sep.c и header.h. Он содержит два объявления структуры struct { int a; char b; } один в контейнере структуры, а другой в функции print. Эти структуры объявлены в той же единице перевода.

6.2.7 Совместимый тип и составной тип

  1. Два типа имеют совместимый тип, если их типы одинаковы. Дополнительные правила определения совместимости двух типов описаны в 6.7.2 для спецификаторов типов, в 6.7.3 для классификаторов типов и в 6.7.6 для деклараторов. Более того, два типа структуры, объединения или перечисления объявлены в отдельном переводе...

оставшийся текст относится к типам, объявленным в отдельных единицах перевода.

Поскольку структуры не объявляются в отдельных единицах перевода, они не подпадают под правило 6.2.7.

Поэтому в моей интерпретации структуры, одна в контейнере структуры, а другая в приведении в print(), несовместимы.

Другие вопросы по тегам