Совместимые типы и структуры в C
У меня есть следующий код:
int main(void)
{
struct { int x; } a, b;
struct { int x; } c;
struct { int x; } *p;
b = a; /* OK */
c = a; /* Doesn't work */
p = &a; /* Doesn't work */
return 0;
}
который не компилируется под GCC (3.4.6) со следующей ошибкой:
test.c:8: error: incompatible types in assignment
test.c:9: warning: assignment from incompatible pointer type
Теперь, из того, что я понимаю (по общему признанию, из стандарта C99), заключается в том, что a
и c
должны быть совместимыми типами, поскольку они соответствуют всем критериям в разделе 6.2.7, параграф 1. Я пробовал компиляция с std=c99
, безрезультатно.
Предположительно, моя интерпретация стандарта неверна?
Добавление
Кстати, этот вопрос возникает из-за того, что я хотел объявить некоторые шаблонные макросы, чтобы обернуть различные типы данных без накладных расходов, чтобы объявить имена типов /typedef всюду, например. тривиальный пример:
#define LINKED_LIST(T) \
struct { \
T *pHead; \
T *pTail; \
}
...
LINKED_LIST(foo) list1;
LINKED_LIST(foo) list2;
...
LINKED_LIST(foo) *pList = &list1; /* Doesn't work */
Ответы
Ответ 1
Глядя на черновик спецификации Я предполагаю, что вы полагаетесь на условия, которые появляются после утверждения:
Кроме того, два типа структуры, объединения или перечисления, объявленные в отдельных единицах перевода, совместимы, если их теги и члены удовлетворяют следующим требованиям...
Я думаю, что тот факт, что все они деканированы в одном файле C, означает, что они находятся в одной единицы перевода.
Полагаю, что это гарантирует, что если два файла C содержат заголовок, который объявляет тип, то экземпляры этого типа будут совместимы.
Ответ 2
struct { int x; }
является тегом анонимной структуры, две анонимные структуры не могут иметь одно и то же имя, что является необходимым условием совместимости типов. Вы можете объявлять типы, совместимые с неанонимной структурой, с помощью typedef
.
struct tmp { int x; }; // declare structure tag
typedef struct tmp type1;
typedef struct tmp type2; // declare 3 types compatible with struct tmp
typedef struct tmp type3; // and with each other
type1 a, b;
type2 c;
type3 *p;
b = a;
c = a;
p = &a;
Ответ 3
Совместимость структур, объединений и перечислений
Внутри одного исходного файла каждая структура или определение объединения создает новый тип, который не является ни тем же, ни совместимым с любым другой структуры или типа объединения. Однако спецификатор типа, который является ссылка на ранее определенную структуру или тип объединения одинакова тип. Тег связывает ссылку с определением и эффективно действует как имя типа. Чтобы проиллюстрировать это, только типы структур j и k совместимы в этом примере:
struct { int a; int b; } h;
struct { int a; int b; } i;
struct S { int a; int b; } j;
struct S k;
Совместимые структуры могут быть назначены друг другу.
Ответ 4
Интересно, что Clang дает следующее:
error: incompatible type assigning 'struct <anonymous>', expected 'struct <anonymous>'
warning: incompatible pointer types assigning 'struct <anonymous> *', expected 'struct <anonymous> *'
Кажется, что если объявляются две (или более) анонимные структуры, то компилятор делает некоторую внутреннюю магию, которая указывает, какая именно анонимная структура также передается.
Ответ 5
Учитывая пункты 6.2.7 (совместимые типы) и 6.5.16.1 (правила назначения), я понимаю то же, что и вы.
Похоже, что с вашим кодом GCC ведет себя, как если бы ваши определения структуры помечены разными тегами (что не так). В случаях, когда типы случаев не были бы совместимыми. Однако он по-прежнему выглядит как ошибка gcc.
Любая обратная связь от других компиляторов, реализующих стандарт C99?