tags:

views:

1118

answers:

4

Hello, 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;
A: 

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;
Fredrik Jansson
+4  A: 
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.

Lars Wirzenius
+1  A: 

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?

Tim Post
+1  A: 

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
Pete Kirkham