3.8 Type Definition

The keyword typedef is used to define a type synonym. In such a definition, the identifiers name types instead of objects. One such use is to define an abbreviated name for a lengthy or confusing type definition.

A type definition does not create a new basic data type; it creates an alias for a basic or derived type. For example, the following code helps explain the data types of objects used later in the program:

typedef float *floatp, (*float_func_p)();

The type floatp is now "pointer to a float value" type, and the type float_func_p is "pointer to a function returning float ".

A type definition can be used anywhere the full type name is normally used (you can, of course, use the normal type name). Type definitions share the same name space as variables, and defined types are fully compatible with their equivalent types. Types defined as qualified types inherit their type qualifications.

Type definitions can also be built from other type definitions. For example:

typedef char byte;
typedef byte ten_bytes[10];

Type definition can apply to variables or functions. It is illegal to mix type definitions with other type specifiers. For example:

typedef int *int_p;
typedef unsigned int *uint_p;
unsigned int_p x;           /*  Invalid   */
uint_p y;                   /*  Valid     */

Type definitions can also be used to declare function types. However, the type definition cannot be used in the function's definition. The function's return type can be specified using a type definition. For example:

typedef unsigned *uint_p;   /* uint_p has type "pointer to unsigned int"    */
uint_p xp;
typedef uint_p func(void);  /* func has type "function returning pointer to */
                            /* unsigned int                                 */
func f;
func b;
  func f(void)              /* Invalid -- this declaration specifies a      */
                            /* function returning a function type, which    */
  {                         /* is not allowed                               */
    return xp;
  }

uint_p b(void)              /* Legal - this function returns a value of
  {                         /* type uint_p.                                 */
   return xp;
  }

The following example shows that a function definition cannot be inherited from a typedef name:

typedef int func(int x);
func f;
func f         /*  Valid definition of f with type func                  */
{
  return 3;
}              /* Invalid, because the function's type is not inherited  */

Changing the previous example to a valid form results in the following:

typedef int func(int x);
func f;
int f(int x)   /*  Valid definition of f with type func           */
{
  return 3;
}              /* Legal, because the function's type is specified */

You can include prototype information, including parameter names, in the typedef name. You can also redefine typedef names in inner scopes, following the scope rules explained in Section 2.3.


Previous Page | Next Page | Table of Contents | Index