In this SO question I've encountered a very weird typedef
:
struct Date { int day, month, year; } typedef date_s;
I've always been seeing typedef
s following this 'rule':
typedef <existing> <new>;
For example:
typedef unsigned long long ull; typedef int kph; // speed typedef void (*alpm_cb_log)(alpm_loglevel_t, const char *, va_list); typedef int int_t; typedef char char_t, *char_p, (*fp)(void);
The 4th one is taken from here, the 5th and 6th are from cppreference
And this is how I would typedef
a struct
:
typedef struct { int a, b, c; } data; // and then use it data Something;
The question is how is this even possible to write such a typedef
? It doesn't even make sense (at least to me).
clang
doesn't give any errors or warnings, even with -Wall -Wextra
.
Bonus question: should I advise the author of the question where this code could be found to avoid using such a typedef
(because it's very unusual and may lead to confusion)?
typedef is used to define new data type names to make a program more readable to the programmer. For example: | main() | main() { | { int money; | typedef int Pounds; money = 2; | Pounds money = 2 } | } These examples are EXACTLY the same to the compiler.
typedef is a reserved keyword in the programming languages C and C++. It is used to create an additional name (alias) for another data type, but does not create a new type, except in the obscure case of a qualified typedef of an array type where the typedef qualifiers are transferred to the array element type.
Typedefs provide a level of abstraction away from the actual types being used, allowing you, the programmer, to focus more on the concept of just what a variable should mean. This makes it easier to write clean code, but it also makes it far easier to modify your code.
Typedef cannot be used to change the meaning of an existing type name (including a typedef-name). Once declared, a typedef-name may only be redeclared to refer to the same type again.
It turns out that typedef
can be placed after the existing type (in addition to before it). This little oddity, now obsolescent*, is caused by the way in which the C standard "bundles" typedef
s with storage class specifiers, such as static
and auto
:
A declaration is defined as follows:
<declaration> ::= {<declaration-specifier>}+ {<init-declarator>}*
This means that declaration specifiers can appear in any order. Now, declaration specifier is
<declaration-specifier> ::= <storage-class-specifier> | <type-specifier> | <type-qualifier>
And storage class specifier is
<storage-class-specifier> ::= auto | register | static | extern | typedef
The declaration of the struct
's elements is a type specifier. Like typedef
keyword, it is a declaration specifier. Since declaration specifiers can appear in any order, both placements of typedef
(i.e., before and after the struct
) are valid and identical to each other.
*N1570, 6.11.5: "The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature." Thanks, Keith Thompson, for a great comment!
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