typedef struct p *q;
int main()
{
struct p
{
int x;
char y;
q ptr;
};
struct p p = {1, 2, &p};
printf("%dn", p.ptr->x);
return 0;
}
上述程序抛出以下编译错误:
1.c:24: error: dereferencing pointer to incomplete type
但是,如果我将typedef
移动到主func
或将结构定义移动到主之外,则没有编译错误。谁能解释为什么会这样?
内部struct p
对main
函数之外的程序不可见。把你的结构放在main
外面。
您对内部和外部结构p
的相同名称感到困惑。将外部p
定义为
typedef struct p *q;
什么意思?这意味着您正在定义一个新类型q
它是指向结构p
的指针。但问题是这里没有已知的struct p
类型的定义。
的确,外p
对main
可见,但内p
对外p
不可见。
struct p
在main()
内部定义,对外部函数不可见。 您可以通过将struct p
放在主(全局)之外来解决编译错误。
这受 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
不完整,因此尝试使用它会导致错误。
也许这能更好地说明问题:
#include <stdio.h>
struct foo {
int a, b;
};
int main(void) {
printf( "sizeof outer struct: %zun", sizeof(struct foo) );
struct foo { int a; };
printf( "sizeof inner struct: %zun", sizeof(struct foo) );
return 0;
}
输出(在我的机器上,但确切的值无关紧要):
sizeof outer struct: 8
sizeof inner struct: 4
您隐藏了外部定义,类似于隐藏变量的方式。
呵呵