为什么编译这段代码没有错误?这是一个gcc bug吗?

即使struct中的char * name声明没有分号,下面的代码也会成功编译.

#include<stdio.h>

typedef struct map
{
   int id;
   char *name
}map;

int main()
{
    return 0;
}

最佳答案 从C2011开始的struct和union声明的语法:

struct-or-union-specifier:
    struct-or-union identifieropt { struct-declaration-list }
    struct-or-union identifier

struct-or-union:
    struct
    union

struct-declaration-list:
    struct-declaration
    struct-declaration-list struct-declaration

struct-declaration:
    specifier-qualifier-list struct-declarator-listopt ;
    static_assert-declaration

specifier-qualifier-list:
    type-specifier specifier-qualifier-listopt
    type-qualifier specifier-qualifier-listopt

struct-declarator-list:
    struct-declarator
    struct-declarator-list , struct-declarator

struct-declarator:
    declarator
    declaratoropt : constant-expression

static_assert-declaration:
    _Static_assert ( constant-expression , string-literal ) ;

C 2011 Online Draft,6.7.2.1

它非常明确 – struct-declaration-list中的每个声明都必须以; – 在结束前没有允许删除分号}.除非你以某种方式压制它,否则gcc应该在这里发出诊断信息. “

编辑

Myst在这里提出了一个有效点 – gcc发出警告,但不会停止转换并仍然生成可执行文件(除非我指定-Werror或类似的东西).但是,它为什么这样做与6.7.2.1/8无关.原因是这个特定的语法错误相对容易恢复 – 缺少所需的分号,但由于下一个标记是结构或联合定义的结束},编译器可以安全地假设它被看作是有效的成员声明并移动上. gcc发出警告(因为必须在语法违规时发出诊断),但此时没有理由停止转换.

Myst引用的段落与情况有关

struct foo;

struct bar {
  struct foo blah;
};

当我们尝试声明blah成员时,struct foo类型还没有完成;编译器不知道要为它预留多少空间.在我们看到它的定义的结束之前,struct foo将不会完成,所以在那之前我们不能创建struct foo的实例.

为了扩展我在评论中提出的观点,C标准不区分“警告”和“错误” – 它只要求在语法错误或约束违反时发出某种诊断:

5.1.1.3 Diagnostics

1    A conforming implementation shall produce at least one diagnostic message (identified in
an implementation-defined manner) if a preprocessing translation unit or translation unit
contains a violation of any syntax rule or constraint, even if the behavior is also explicitly
specified as undefined or implementation-defined. Diagnostic messages need not be
produced in other circumstances.9)

9) The intent is that an implementation should identify the nature of, and where possible localize, each
violation. Of course, an implementation is free to produce any number of diagnostics as long as a
valid program is still correctly translated. It may also successfully translate an invalid program.

个别编译器可以决定特定诊断是否被视为“警告”或“错误”,并且他们可以决定是否停止特定错误的转换.与上面的段落一样,允许编译器翻译无效程序.

点赞