On 2/24/23 16:04, Eric Blake wrote: > @@ -176,7 +176,10 @@ > { \ > return bsearch (key, v->ptr, v->len, sizeof (type), \ > (void *) compare); \ > - } > + } \ > + \ > + /* End with duplicate declaration, so callers must supply ';' */ \ > + typedef struct name name > > #define empty_vector { .ptr = NULL, .len = 0, .cap = 0 } >
This does not conform to C99. In C99 6.7 "Declarations" p3 (under "Constraints"), we have If an identifier has no linkage, there shall be no more than one declaration of the identifier (in a declarator or type specifier) with the same scope and in the same name space, except for tags as specified in 6.7.2.3. And in p5 (under "Semantics"), we have A declaration specifies the interpretation and attributes of a set of identifiers. A /definition/ of an identifier is a declaration for that identifier that: — for an object, causes storage to be reserved for that object; — for a function, includes the function body; 101) — for an enumeration constant or typedef name, is the (only) declaration of the identifier. Consider the source code "typedef.c": ----- struct s { int x; }; typedef struct s s; typedef struct s s; ----- When built with $ gcc -std=c99 -pedantic -fsyntax-only typedef.c we get ----- typedef.c:3:18: warning: redefinition of typedef ‘s’ [-Wpedantic] 3 | typedef struct s s; | ^ typedef.c:2:18: note: previous declaration of ‘s’ with type ‘s’ 2 | typedef struct s s; | ^ ----- What does work is plain "struct s" though: ----- struct s { int x; }; typedef struct s s; struct s; ----- and that's because of the above-cited C99 6.7.2.3 reference (specifically p9): If a type specifier of the form struct-or-union identifier or enum identifier occurs other than as part of one of the above forms, and a declaration of the identifier as a tag is visible, then it specifies the same type as that other declaration, and does not redeclare the tag. Laszlo _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://listman.redhat.com/mailman/listinfo/libguestfs