typedef struct p *q;
int main()
{
struct p
{
int x;
char y;
q ptr;
};
struct p p = {1, 2, &p};
printf("%d\n", p.ptr->x);
return 0;
}
上述程序抛出以下编译错误:
1.c:24: error: dereferencing pointer to incomplete type
但是,如果我在main typedef
内移动func
或者如果我将结构定义移到main之外,则没有编译错误。
谁能解释为什么会发生?
答案 0 :(得分:3)
struct p
对main
函数之外的程序不可见。将您的结构放在main
之外。p
的相同名称感到困惑。您将外部p
定义为
typedef struct p *q;
这是什么意思?这意味着您要定义一个新类型q
,它是指向结构p
的指针。但问题是这里没有struct p
类型的定义
确实外p
对main
可见,但内p
对外p
不可见。
答案 1 :(得分:2)
struct p
在main()
内定义,对外部函数不可见。您可以通过将struct p
放在main(全局)之外来解决编译错误。
答案 2 :(得分:1)
这受C 2011 6.7.2.3第4和第5段的管辖:
4具有相同范围且使用相同标记的结构,联合或枚举类型的所有声明声明相同的类型...
5结构,联合或枚举类型的两个声明在不同的范围或使用不同的标签声明了不同的类型。
因为typedef struct p *q;
不在任何函数之内,所以它具有文件范围。由于struct p { int x; … }
位于main
内,因此其范围在main内。因为这两个声明在不同的范围内,所以它们声明了不同的类型。因此,第二项声明未完成struct p
的第一次声明;它声明了一个不同的struct p
。
反过来,这意味着类型q
是指向文件范围struct p
的指针,而不是指向主范围struct p
的指针。由于文件范围struct p
不完整,因此尝试使用它会导致错误。
答案 3 :(得分:0)
也许这说明事情好一点:
#include <stdio.h>
struct foo {
int a, b;
};
int main(void) {
printf( "sizeof outer struct: %zu\n", sizeof(struct foo) );
struct foo { int a; };
printf( "sizeof inner struct: %zu\n", sizeof(struct foo) );
return 0;
}
输出(在我的机器上,但确切的值无关紧要):
sizeof outer struct: 8
sizeof inner struct: 4
您正在隐藏外部定义,类似于隐藏变量的方式。
HTH