I stumbled upon some code where the typedef
keyword is in between the type and the alias name like in
int typedef INT;
It compiles
If you look at 7.1/1 you see this grammar for decl-specifier:
, which shows that a type-specifier
and the typedef
keyword fall at the same point in the grammar, allowing you to interchange them as in the question (although as an aside never write code like this, it's not idiomatic at all).
decl-specifier:
storage-class-specifier type-specifier function-specifier friend typedef
The typedef
keyword is classified as a storage class specifier in C, though the standard explicitly remarks that that's for convenience in expressing the formal language syntax. It nevertheless follows that typedef
can appear in exactly the same places that any other storage class specifier, such as extern
or static
, can appear. [C2011, 6.7.1/5]
In fact, the syntax allows storage-class specifiers to be intermixed with type specifiers, type qualifiers, and other "declaration specifiers" in declarations. [C2011, 6.7/1, 6.7/6]
Thus, yes, it is valid to put the typedef
keyword after the type name, as in your example.
I compile using:
gcc -c -Wall -Wextra -pedantic -Wconversion -std=gnu99
In the background, this means -Wold-style-declaration
is set.
Then the compiler outputs the following warning message:
warning: 'typedef' is not a beginning of declaration [-Wold-style-declaration]
without that parameter being set, the compiler handles the syntax with no problems
So the posted syntax is within the standard, but can be confusing to the reader.
TL/DR Version
Yes, int typedef INT
is conforming.
James Michener Version
C declaration syntax (C 2011 online draft):
6.7 Declarations
Syntax
1declaration:
declaration-specifiers init-declarator-listopt ;
static_assert-declaration
declaration-specifiers:
storage-class-specifier declaration-specifiersopt
type-specifier declaration-specifiersopt
type-qualifier declaration-specifiersopt
function-specifier declaration-specifiersopt
alignment-specifier declaration-specifiersopt
...
What this says is that in a single declaration you can have a sequence of one or more declaration specifiers, where each declaration specifier can be a storage class specifier (auto
, extern
, static
, typedef
), a type specifier (int
, float
, char
, etc.), a type qualifier (const
, restrict
, volatile
, etc.), a function specifier (inline
), or an alignment specifier.
The order in which various specifiers appear doesn't matter; static const short int x;
may be written as int static short const x
, or int short const static x
, etc. As a matter of practice, most people put the storage class specifier first, then any function or alignment specifiers (if necessary), then any type qualifiers, then type specifiers, so static const short int x
is how most people would write that declaration.
This syntax is what allows us to write types like long double
or long long
or unsigned long int
, etc.
Note that while the syntax allows arbitrary (and arbitrarily long) sequences of type specifiers, there's a semantic rule that only allows a relative few. You can't write short short short short x
, for example, or long long long double y
. Only the following sequences are allowed:
Constraints
2 At least one type specifier shall be given in the declaration specifiers in each declaration, and in the specifier-qualifier list in each struct declaration and type name. Each list of type specifiers shall be one of the following multisets (delimited by commas, when there is more than one multiset per item); the type specifiers may occur in any order, possibly intermixed with the other declaration specifiers.
—void
—char
—signed char
—unsigned char
—short, signed short, short int, or signed short int
—unsigned short, or unsigned short int
—int, signed, or signed int
—unsigned, or unsigned int
—long, signed long, long int, or signed long int
—unsigned long, or unsigned long int
—long long, signed long long, long long int, or
signed long long int
—unsigned long long, or unsigned long long int
—float
—double
—long double
—_Bool
—float _Complex
—double _Complex
—long double _Complex
— atomic type specifier
— struct or union specifier
— enum specifier
— typedef name
Addendum
As Keith points out in the comment below, a future revision of the language may limit storage class specifiers to the beginning of the declaration, so int typedef INT
may not be legal under a future compiler.
typedef int INT
RightWay to use typedef
Wherever you use INT it will be replace by int datatype
This main purpose is to only for long data string to simple value but in this case you can use normal int itself
You can relay on just for test purpose use debugging you can understand very well