Concepts / Understanding Type Aliases

Understanding Type Aliases

A type alias is an alternative name for an existing type, not a new type.

  • Programming

Writing Code Once, Running It Twice

Programs are often written once and then compiled and run on different systems. A program that works on one system should ideally work on another without its source code being rewritten. This goal is called portability, and it is one of the main reasons programmers use type aliases. To see why, we first need to look at a type whose exact definition is not fixed.

What do you think happens?

A programmer writes the name size_t in the same source file and compiles it on two different implementations. Do both builds necessarily use the same underlying type for that name?

  • Yes, the name always refers to the same type everywhere

  • No, the same name can refer to different underlying types depending on the implementation

Reveal answer
Answer:

No, the same name can refer to different underlying types depending on the implementation.

Some types are implementation-dependent. The type named size_t is one of them: in one implementation it may be an unsigned int, while in another the same name may refer to an unsigned long. The written name looks identical in both places, but the type behind it is not guaranteed to be the same.

An Alias Is a Name, Not a New Type

Definition

A type alias is an alternative name for an existing type. It is not a new type. The alias is the name the programmer writes, and the underlying type is the existing type that the name stands for.

The direction of this relationship matters. Writing the alias is the same as writing the type it names. The alias gives the programmer a convenient label without changing what the type is. Nothing about the underlying type becomes different because it has been given a second name, so an alias should never be thought of as a separate kind of type with its own behavior.

size_talias written in codeunderlying typeexisting type the namestands forstands for
The programmer writes the alias name, and that name stands for the existing underlying type. The alias itself adds a label, not a new type.

Why an Implementation-Dependent Type Causes Trouble

The difficulty begins with types whose exact definition is not fixed. Some types are defined differently by different implementations. This means the same type name can refer to a different underlying type depending on where the program is built.

Consider what happens if code uses such a type by its underlying name. That code is tied to one particular implementation. When the program is moved to an implementation that defines the type differently, the written code no longer matches the underlying type everywhere it is used, and the programmer must find and change those lines. Repeated across a large program, this makes moving code between platforms slow and error-prone.

Tracing One Name Across Two Implementations

The name size_t is the running example here. The type it names is implementation-dependent. On one implementation, the name may refer to an unsigned int. On another, the same written name may refer to an unsigned long. A reader sees size_t in both places and reads the same text, but the underlying type behind that text is not the same everywhere.

size_talias name in sourceImplementation Aunsigned intImplementation Bunsigned longmaps to on Amaps to on B
For the single alias name size_t, the underlying type it maps to depends on which implementation compiles the code.

How an Alias Keeps Code Unchanged

Here is the central benefit of the alias. The alias can be defined to match whatever the current implementation uses. The code that names the alias keeps working without modification, because the programmer never wrote the underlying type name. The programmer writes the alias once, and the choice of underlying type is made by the implementation.

Source textsize_tUnderlying typeunsigned int onImplementation ASource textsize_tUnderlying typeunsigned long onImplementation Bresolves toresolves to
The source text stays the same across both builds. Only the underlying type beneath the alias changes when the implementation changes.

Readers of the code also benefit. The alias names the purpose of the value, so a reader who sees size_t understands that the type has been chosen to suit the implementation. It is not a fixed choice made by the author of the code.

Worked Example: Moving a Program Between Implementations

Worked example

Keeping a Program Portable

A team has a program that declares a value to hold a size or count using the alias size_t. They need to build the same program on a second implementation. Which lines of source text must change?

  1. 1
    Identify what the source names

    Every declaration uses the alias size_t, not the underlying type name. The source text names the alias, not a concrete type.

  2. 2
    Recall what the alias stands for

    The alias is only a label. On the second implementation it may stand for a different underlying type, but that choice is already handled by the implementation's definition of the alias.

  3. 3
    Check for hard-coded types

    The team searches for the underlying type names written directly in the code. Any such line is tied to one implementation and would need editing.

  4. 4
    Conclude what changes

    If the code uses only the alias, no declaration needs rewriting. The build simply uses the underlying type that the second implementation defines for that alias.

Result

A program that writes only the alias keeps its source text unchanged when moved. Only hard-coded underlying type names would require edits.

Common Mistakes That Weaken Portability

Using an alias gives portability only when the code is written to use the alias consistently. The following mistakes undo the benefit even though an alias appears in the program.

  • Common mistake

    Writing the underlying type directly instead of the alias

    What it looks like

    Declaring a variable with the underlying type name in one place and the alias in another

    Why it fails

    Writing the underlying type ties that line to one implementation, so it will not follow the alias when the code moves to another implementation.

    Do this instead

    Write the alias everywhere the value has that purpose.

  • Common mistake

    Assuming one fixed meaning for an alias

    What it looks like

    Believing that size_t always refers to unsigned long because it did on one machine

    Why it fails

    The same alias can refer to different underlying types on different implementations, so an assumption based on one build is not reliable on another.

    Do this instead

    Treat the alias as a label whose underlying type is decided by the implementation, and do not rely on a particular underlying type.

  • Common mistake

    Treating the alias as a separate new type

    Why it fails

    An alias is an alternative name for an existing type. It does not create a new distinct type with its own rules.

    Do this instead

    Reason about the alias by reasoning about the type it names.

ApproachWhat the source text namesEffect when moved to another implementation
Using the alias size_tThe alias nameSource text stays the same; the implementation supplies the underlying type
Hard-coding an underlying typeA concrete type such as unsigned intThe line stays tied to one implementation and may need editing

Using the alias versus hard-coding the underlying type

Practice: Choosing the Portable Form

EASY

A colleague's code declares a counter with the underlying type name unsigned long because it worked on their machine. Rewrite the idea in your own words: what should the declaration name instead, and why does that keep the code portable across implementations?

Hints
  • Ask what the declaration is for: the purpose of the value is what the alias names.
  • Think about whether the underlying type is fixed or decided by the implementation.
  • Consider what must be edited if the program moves to an implementation where the underlying type differs.

Key Takeaways

  • A type alias is an alternative name for an existing type, not a new type; writing the alias is the same as writing the type it names.
  • Some types are implementation-dependent, so the same name such as size_t can refer to different underlying types on different implementations.
  • Code that uses an alias rather than the underlying type name can be written once and reused across implementations without modification.
  • Portability is weakened by hard-coding underlying types or by assuming one fixed meaning for an alias.

More concepts starting with U