【问题标题】:What is the differences about struct in C99 to ANSI-C?C99 中的 struct 与 ANSI-C 有什么区别?
【发布时间】:2010-10-03 17:31:56
【问题描述】:

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

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

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

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

Edit2:这里是夹板的输出:

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;

【问题讨论】:

  • 你确定?带有-ansi -pedantic 的 GCC 可以很好地编译它...
  • ANSI C 是(ISO 的美国副本)标准 C 语言,经过多年的标准化,有多个版本:89、95、99。因此有 ASNI C99 这样的东西,但 ANSI C 是模棱两可的(指所有版本)
  • “ANSI C”的口语意思是 ANSI X3.159-1989 aka C89 - 我从来没有听说过有人用“ANSI C”这个词来指代其他任何东西......
  • @Christoph:也许对你来说,但对于一般性问题,它们都是 ANSI C。如果你指的是特定版本,那么......
  • @MSalters:实际上,没有 ANSI C99 之类的东西——ISO C99 在 2000 年被 ANSI 采用

标签: c struct c99 splint


【解决方案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

【讨论】:

    【解决方案2】:
    struct { int x; int y; } z;
    

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

    ofaurax,你得到什么错误信息来断定它不起作用?

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

    编辑:

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

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 2013-06-16
          • 1970-01-01
          • 1970-01-01
          • 2011-11-14
          • 1970-01-01
          • 2014-06-17
          • 1970-01-01
          • 2011-05-13
          • 2011-07-15
          相关资源
          最近更新 更多