C语言 使用 typedef 和结构时出错


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 pmain函数之外的程序不可见。把你的结构放在main外面。
您对内部和外部结构p的相同名称感到困惑。将外部p定义为

typedef struct p *q;  

什么意思?这意味着您正在定义一个新类型q它是指向结构p的指针。但问题是这里没有已知的struct p类型的定义。
的确,pmain可见,但内p对外p不可见

struct pmain()内部定义,对外部函数不可见。 您可以通过将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

您隐藏了外部定义,类似于隐藏变量的方式。

最新更新