1

このコードは ANSI-C では正しくないように見えますが、C99 では問題ありません。

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

C99 と ANSI-C の struct の違いは何ですか?

編集:「a」を忘れました、悪いです。このコードは、C99 モードの gcc で問題なくコンパイルされますが、すべての C99 拡張機能をサポートしていないことが知られている splint では解析エラーになります。

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

4 に答える 4

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

このコードは、1978 年以降の C のすべてのバージョンから、おそらくそれよりもずっと前から、同じセマンティクスを持つ有効な C です。これは、2 つの int で構成される名前のない構造体型を型として持つ、z と呼ばれる変数を定義します。

ofaurax さん、それが機能しないと結論付けるには、どのようなエラー メッセージが表示されますか?

(ペダンティック ニット: 「ANSI C」は、ANSI (American National Standards Institute) によって標準化された C のバージョンを意味します。1989 年バージョンの ANSI C 標準は、国際標準化機構 (ISO) によって採用されました。1999 年に、ISO は新しいバージョンのANSI がその後採用した C 標準)。

編集:

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

これは、2 つの int とその型の変数 z で構成される「struct a」と呼ばれる構造体型を定義します。これは、1978 年版の C ("K&R") でも整形式です。分割とは何かはわかりませんが、正確なエラー メッセージは問題の原因を突き止めるのに役立つでしょう。

于 2009-01-27T10:48:37.533 に答える
1

そのコードだけが含まれているファイルは、Splint3.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
于 2009-01-27T11:44:12.477 に答える
1

実際のコンパイラ警告、コンパイラ フラグ、および関連するコード行を表示できますか? あなたの例にはまったく問題はありません。それとも、結論に至ったドキュメントへのリンクですか?

違いを教えてくれるコンパイラを信頼している場合、どのコンパイラ/バージョンを使用していますか?

于 2009-01-27T11:03:33.977 に答える
0

確かではありませんが、「古い」コンパイラでは、次のように記述しなければならなかったことを覚えています

typedef struct _Z {int x; int y;} z; or just typedef struct {int x; int y;} z;
于 2009-01-27T10:36:26.827 に答える