有关C99与ANSI-C中struct的区别是什么?

时间:2009-01-27 10:24:13

标签: c struct c99 splint

此代码在ANSI-C中似乎不正确,但在C99中可以正确:

struct a { int x; int y; } z;

C99和ANSI-C中struct的区别是什么?

编辑:我忘记了“a”,我的不好。此代码在C99模式下使用gcc编译正常,但是在splint上是一个解析错误,已知它不支持所有C99扩展。

Edit2:这是splint的输出:

Splint 3.1.2 --- 19 Dec 2007

build/ecos_install/include/cyg/fileio/fileio.h:151:5:
Parse Error. Attempting to continue.
build/ecos_install/include/cyg/fileio/fileio.h:151:25:
Cannot recover from parse error.
*** Cannot continue.

Edit3:这个文件是eCos fileio.h(这个片段的最后一行是第152行):

typedef CYG_ADDRWORD cyg_dir;

//=============================================================================
// Filesystem table entry

typedef int     cyg_fsop_mount    ( cyg_fstab_entry *fste, cyg_mtab_entry *mte );
typedef int     cyg_fsop_umount   ( cyg_mtab_entry *mte );
typedef int     cyg_fsop_open     ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
                                    int mode,  cyg_file *fte );
typedef int     cyg_fsop_unlink   ( cyg_mtab_entry *mte, cyg_dir dir, const char *name );
typedef int     cyg_fsop_mkdir    ( cyg_mtab_entry *mte, cyg_dir dir, const char *name );
typedef int     cyg_fsop_rmdir    ( cyg_mtab_entry *mte, cyg_dir dir, const char *name );
typedef int     cyg_fsop_rename   ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1,
                                    cyg_dir dir2, const char *name2 );
typedef int     cyg_fsop_link     ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1,
                                    cyg_dir dir2, const char *name2, int type );
typedef int     cyg_fsop_opendir  ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
                                    cyg_file *fte );
typedef int     cyg_fsop_chdir    ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
                                    cyg_dir *dir_out );
typedef int     cyg_fsop_stat     ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
                                    struct stat *buf);
typedef int     cyg_fsop_getinfo  ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
                                    int key, void *buf, int len );
typedef int     cyg_fsop_setinfo  ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
                                    int key, void *buf, int len );


struct cyg_fstab_entry
{
    const char          *name;          // filesystem name
    CYG_ADDRWORD        data;           // private data value
    cyg_uint32          syncmode;       // synchronization mode

    cyg_fsop_mount      *mount;
    cyg_fsop_umount     *umount;
    cyg_fsop_open       *open;
    cyg_fsop_unlink     *unlink;
    cyg_fsop_mkdir      *mkdir;
    cyg_fsop_rmdir      *rmdir;
    cyg_fsop_rename     *rename;
    cyg_fsop_link       *link;
    cyg_fsop_opendir    *opendir;
    cyg_fsop_chdir      *chdir;
    cyg_fsop_stat       *stat;
    cyg_fsop_getinfo    *getinfo;
    cyg_fsop_setinfo    *setinfo;
} CYG_HAL_TABLE_TYPE;

4 个答案:

答案 0 :(得分:4)

struct { int x; int y; } z;

此代码是有效的C,具有相同的语义,从1978年以来的每个版本的C开始,可能更早。它定义了一个名为z的变量,它的类型为无名结构类型,由两个整数组成。

ofaurax,你得到的结论是什么错误消息不起作用?

(Pedantic nit:“ANSI C”是指由ANSI,美国国家标准协会标准化的C版本.1989版ANSI C标准被ISO,国际标准组织采用。1999年ISO制作了新版本ANSI标准的版本,然后由ANSI采用。)

编辑:

struct a { int x; int y; } z;

这定义了一个结构类型,称为“struct a”,由两个整数和一个该类型的变量z组成。即使在1978年的C版(“K& R”)中,这仍然是良好的形成。我不知道什么是分裂,但确切的错误消息仍然可能帮助我们找出问题所在。

答案 1 :(得分:1)

不太确定,但在“旧”编译器中,我记得必须将其写为

typedef struct _Z {int x; int y;} z; or just typedef struct {int x; int y;} z;

答案 2 :(得分:1)

您能否显示实际的编译器警告,编译器标志以及代码的相关行?你的例子绝对没有错。或者,也许是指向您的结论的文档链接?

如果您信任编译器告诉您差异,您使用的编译器/版本是什么?

答案 3 :(得分:1)

Splint 3.1.2正好解析了包含该代码的文件。

你能提供一个简单,完整的例子,展示你所描述的行为吗?

一点点实验表明,splint似乎不支持混合代码和声明,这会让我不再使用它。所以你自己发布的代码是可以的,但这会产生一个解析错误:

void foo () {
   int x = 1;
   ++x;
   struct a { int x; int y; } z;
}

对语法的这种改变将允许它解析上面的简单混合代码和声明,然后出现才能工作,但我没有详尽地测试它。

$ diff original/src/cgrammar.y src/cgrammar.y
1711a1712
>  | initializer