I have the following (working) code in an existing code base, used in include file that is shared between C and C++, compiling on MSVC (2010) and Windows DDK:
struct X {
USHORT x;
} typedef X, *PX;
And:
enum MY_ENUM {
enum_item_1,
enum_item_2
} typedef MY_ENUM;
As far as I know, correct definition should look like this:
typedef struct {
USHORT x;
} X, *PX;
Is there any purpose for having the form below? Am I missing something?
The fact that both typedef <type> <alias>
and <type> typedef <alias>
are valid simply comes from the language grammar definition.
typedef
is classified as a storage-class specfifier (just like static
, auto
), and the type itself is known as the type-specifier. From the syntax definitions in section 6.7 of the standard, you'll see that these are free to be interchanged:
declaration:
declaration-specifiers init-declarator-list ;
declaration-specifiers:
storage-class-specifier declaration-specifiers
type-specifier declaration-specifiers
type-qualifier declaration-specifiers
function-specifier declaration-specifiers
init-declarator-list:
init-declarator
init-declarator-list , init-declarator
init-declarator:
declarator
declarator = initializer
(Note, of course, that this is equally true for structs and for non-structs, meaning that double typedef trouble;
is also valid.)
As others said, typedef
is a storage-class specifier and as with other storage-class specifiers you are also allowed to put the specifier between the type and the declarator.
While this is valid and it is also a form that should be avoided as C marked it as an obsolescent feature:
(C11, 6.11.5p1) "The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature."
Both have the same meaning. Both of these two forms are valid:
typedef <existing_type> <new_type>
<existing_type> typedef <new_type>
You can typedef
the above struct in either ways:
struct X {
USHORT x;
}typedef X, *PX; // <existing_type> typedef <new_type>
or
typedef struct {
USHORT x;
} X, *PX; // typedef <existing_type> <new_type>
You really are allowed to put all the declaration specifiers in any order you want! The positions of any *
pointers and the actual declarator (the variable or new type name) matter, but all that typedef
int
unsigned
const
static
etc. stuff can be in any order.
If you look at the official grammar of C, it just says:
declaration:
declaration-specifiers init-declarator-list ;
The declaration-specifiers
are all the storage class specifiers (typedef
, extern
, etc.), type specifiers (the actual type, like int
or struct X
), type qualifiers (const
and volatile
), and a few other less common ones. Their order is not important. The second part is the init-declarator-list
, and it's the variable or new type name (in the case of a typedef), any *
characters, the initialization of the variable (int x = 3
), and more. The order of things in the declarator part is important, but not the order in the declaration specifiers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With