编译器在声明未定义类型的指针时未显示错误

时间:2014-09-26 06:58:03

标签: c pointers gcc declaration

我使用gcc编译器编译了以下c代码:

#include <stdio.h>

struct node{
        int info;
        struct test* next;
};

int main()
{
        struct node start;
        struct node* p;
        start.info = 2;
        start.next = (struct test*)&start;
        printf("start.next = %p \n",start.next);
        p = start.next;
        printf("p->info = %d\n",p->info);
}

但令我惊讶的是,在声明next(在structure node中)作为指向未声明类型(struct test)的指针后,仍然编译成功!编制完上述程序后,其打印仅发出如下警告:

test.c:15:4: warning: assignment from incompatible pointer type [enabled by default]
  p = start.next;
    ^

现在我怀疑为什么编译器没有因为没有声明structure test而产生错误?

2 个答案:

答案 0 :(得分:6)

程序中没有未定义的类型。在结构struct test中声明了一个不完整的类型struct node。 您可以使用指向不完整类型的指针。

考虑一个简化的例子

会更清楚
struct node{
        int info;
        struct node* next;
};

在此结构中,指针next也指向不完整类型struct node,因为结构定义仅在结束括号后完成。

一个更有趣的例子。类型void *在C程序中非常常用。但是根据C标准(6.2.5类型,第19页)

  

19 void类型包含一组空值; 它是一个   不完整的对象类型,无法完成。

至于指针本身(C标准,6.2.5类型,第21页)

A pointer type is a complete object type.

关于结构本身(6.7.2.1结构和联合说明符,第8页)

  

8中存在一个struct-declaration-list   struct-or-union-specifier在转换中声明一个新类型   单元。 struct-declaration-list是一系列声明   结构或联盟的成员。如果是struct-declaration-list   不包含命名成员,没有匿名结构,也没有匿名   工会,行为是不确定的。 类型不完整,直到   在终止列表的}之后立即完成   此后

答案 1 :(得分:1)

来自cppreference的explicit type conversion部分:

  

此外,允许使用C风格的演员表格来演绎,演奏和演奏   指向不完整类类型的指针之间。如果表达和   new_type是指向不完整类类型的指针,它未指定   是否选择了static_cast或reinterpret_cast。

struct test*是指向不完整类型的指针。 struct test是一个前向声明,被引入到main的本地范围。