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