Oli*_*rth 20 c gcc type-conversion
我有以下代码:
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;
}
Run Code Online (Sandbox Code Playgroud)
无法在GCC(3.4.6)下编译,但出现以下错误:
test.c:8: error: incompatible types in assignment
test.c:9: warning: assignment from incompatible pointer type
Run Code Online (Sandbox Code Playgroud)
现在,从我的理解(当然从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 */
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
看一下规范草案,我猜你在依赖声明之后的条件:
此外,如果它们的标签和成员满足以下要求,则在单独的翻译单元中声明的两个结构,联合或枚举类型是兼容的......
我认为这些都在同一个C文件中被删除的事实意味着它们在一个翻译单元中.
猜测似乎这可以保证当两个C文件包含一个声明类型的头时,那么该类型的实例将是兼容的.
在单个源文件中,每个结构或联合定义都会创建一个与任何其他结构或联合类型既不相同也不兼容的新类型。但是,作为对先前定义的结构或联合类型的引用的类型说明符是相同的类型。该标记将引用与定义相关联,并有效地充当类型名称。为了说明这一点,在本例中只有结构体 j 和 k 的类型是兼容的:
Run Code Online (Sandbox Code Playgroud)struct { int a; int b; } h; struct { int a; int b; } i; struct S { int a; int b; } j; struct S k;可以将兼容的结构分配给彼此。
| 归档时间: |
|
| 查看次数: |
4900 次 |
| 最近记录: |