typeofAnother way to refer to the type of an expression is with typeof. 
The syntax of using of this keyword looks like sizeof, but the
construct acts semantically like a type name defined with typedef.
   
There are two ways of writing the argument to typeof: with an
expression or with a type.  Here is an example with an expression:
     typeof (x[0](1))
     
This assumes that x is an array of pointers to functions;
the type described is that of the values of the functions.
   
Here is an example with a typename as the argument:
     typeof (int *)
     
Here the type described is that of pointers to int.
   
If you are writing a header file that must work when included in ISO C
programs, write __typeof__ instead of typeof. 
See Alternate Keywords.
   
A typeof-construct can be used anywhere a typedef name could be
used.  For example, you can use it in a declaration, in a cast, or inside
of sizeof or typeof.
   
typeof is often useful in conjunction with the
statements-within-expressions feature.  Here is how the two together can
be used to define a safe "maximum" macro that operates on any
arithmetic type and evaluates each of its arguments exactly once:
     #define max(a,b) \
       ({ typeof (a) _a = (a); \
           typeof (b) _b = (b); \
         _a > _b ? _a : _b; })
     
Some more examples of the use of typeof:
     
y with the type of what x points to.
               typeof (*x) y;
          
     y as an array of such values.
               typeof (*x) y[4];
          
     y as an array of pointers to characters:
               typeof (typeof (char *)[4]) y;
          
     It is equivalent to the following traditional C declaration:
          char *y[4];
          
     To see the meaning of the declaration using typeof, and why it
might be a useful way to write, let's rewrite it with these macros:
     
          #define pointer(T)  typeof(T *)
          #define array(T, N) typeof(T [N])
          
     Now the declaration can be rewritten this way:
          array (pointer (char), 4) y;
          
     Thus, array (pointer (char), 4) is the type of arrays of 4
pointers to char. 
Compatibility Note: In addition to typeof, GCC 2 supported
a more limited extension which permitted one to write
     typedef T = expr;
     
with the effect of declaring T to have the type of the expression
expr.  This extension does not work with GCC 3 (versions between
3.0 and 3.2 will crash; 3.2.1 and later give an error).  Code which
relies on it should be rewritten to use typeof:
     typedef typeof(expr) T;
     
This will work with all versions of GCC.