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

发布于 2024-07-12 05:58:38 字数 3045 浏览 6 评论 0原文

这段代码在 ANSI-C 中似乎不正确,但在 C99 中没问题:

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

What are the Differences about struct in C99 and ANSI-C ?

编辑:我忘了“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;

This code doesn't appear to be correct in ANSI-C, but ok in C99 :

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

What are the differences about struct in C99 and ANSI-C ?

Edit: I forgot the "a", my bad. This code compiles ok with gcc in C99 mode, but is a parse error on splint, which is known to not support all the C99 extensions.

Edit2: here is the output of 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: This file is the eCos fileio.h (the last line of this fragment is line 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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

别再吹冷风 2024-07-19 05:58:38
struct { int x; int y; } z;

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

ofaurax,您从什么错误消息中得出结论它不起作用?

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

编辑:

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

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

struct { int x; int y; } z;

This code is valid C, with the same semantics, from every version of C since 1978 onwards, and probably a lot earlier. It defines a variable, called z, which has as its type a name-less struct type, which consists of two ints.

ofaurax, what error message do you get to conclude it doesn't work?

(Pedantic nit: "ANSI C" means the version of C standardized by ANSI, the American National Standards Institute. The 1989 version of the ANSI C standard was adopted by ISO, the International Standards Organization. In 1999 ISO made a new version of the C standard, which ANSI then adopted back.)

Edit:

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

This defines a struct type, called "struct a", consisting of two ints, and a variable, z, of that type. This is still well-formed even in the 1978 version of C ("K&R"). I don't know what split is, but the exact error messages would still probably help us figure out what the problem is.

梦亿 2024-07-19 05:58:38

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

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

Can you show the actual compiler warnings, compiler flags and the associated lines of your code? There is absolutely nothing wrong with your example. Or, perhaps a link to the document which led you to your conclusions?

If your trusting a compiler to tell you the difference, what compiler / version are you using?

睫毛溺水了 2024-07-19 05:58:38

Splint 3.1.2 可以很好地解析仅包含该代码的文件。

您能否提供一个简单、完整的示例来展示您所描述的行为?

快速进行的一些实验表明夹板似乎不支持混合代码和声明,这会让我放弃使用它。 因此,您发布的代码本身是可以的,但这会产生解析错误:

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

对语法的这种更改将允许它解析上面的简单混合代码和声明,然后出现 可以工作,但我还没有对其进行详尽的测试。

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

A file with just that code in it is parsed fine by Splint 3.1.2.

Can you provide a simple, complete example which exhibits the behaviour you're describing?

A quick bit of experimenting says splint doesn't appear to support mixed code and declarations, which would put me off using it. So the code you posted by itself is ok, but this will give a parse error:

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

This change to the grammar will allow it to parse the simple mixed code and declaration above, and it then appears to work but I've not tested it exhaustively.

$ diff original/src/cgrammar.y src/cgrammar.y
1711a1712
>  | initializer
琉璃繁缕 2024-07-19 05:58:38

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

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

Not too sure, but in "old" compilers I remember having to write that as

typedef struct _Z {int x; int y;} z; or just typedef struct {int x; int y;} z;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文