C++

typeid versus typeof in C

25 September 2026 · 6 min read

typeid versus typeof in C

Navigating the intricacies of C++ can often feel like deciphering a complex puzzle, especially when dealing with type introspection. Developers frequently encounter situations where understanding the precise type of an object or expression becomes crucial for correct program behavior. Two constructs often come up in this context: typeid and typeof. While they both deal with type information, their mechanisms, availability, and use cases differ significantly. Understanding the fundamental distinctions between typeid versus typeof in C++ is essential for writing robust, efficient, and portable code. This article delves deep into what each operator offers, how they operate at different stages of compilation and execution, and when to choose one over the other to effectively manage type information in your C++ applications.

Understanding typeid: Runtime Type Information (RTTI)

The typeid operator is a standard C++ feature, integral to the language’s Runtime Type Information (RTTI) capabilities. It allows programs to discover the actual, dynamic type of an object during program execution. This is particularly useful in polymorphic hierarchies where a base class pointer or reference might point to an object of a derived class. When typeid is applied to a polymorphic class object (one with at least one virtual function), it returns a std::type_info object representing the dynamic type of the object, not just its static (declared) type.

For non-polymorphic types or when applied to expressions, typeid returns the static type. For instance, if you apply typeid to a fundamental type like int or a non-polymorphic class, it will yield information about that specific type at compile time. However, its true power lies in its ability to resolve types at runtime. This dynamic introspection comes with a slight overhead, as the type information needs to be stored and accessed during execution. It’s a cornerstone for features like dynamic_cast, which also relies on RTTI to safely cast pointers or references down a polymorphic hierarchy.

According to the C++ standard, typeid returns a const reference to a std::type_info object, which provides methods like name() (for a human-readable type name), before() (for ordering), and operator== (for comparison). These capabilities enable programs to make decisions based on an object’s actual type at runtime, facilitating flexible and adaptable designs, especially in frameworks or libraries that handle diverse object types. For more detailed insights into typeid and std::type_info, refer to cppreference.com’s documentation on typeid.

Exploring typeof: A Compiler Extension for Compile-Time Types

In contrast to typeid, typeof is not a standard C++ keyword. Instead, it is a non-standard extension primarily provided by GCC (GNU Compiler Collection) and Clang. The typeof operator evaluates the type of an expression at compile time. It’s often used in scenarios similar to C’s typeof operator, allowing developers to declare variables whose type is derived directly from an expression without explicitly naming that type. This can be incredibly useful in generic programming or when dealing with complex template metaprogramming constructs where explicitly writing out a type might be verbose or impossible.

For example, if you have an expression like a + b, where a is an int and b is a double, typeof(a + b) would yield double. This operator is resolved entirely at compile time, meaning it incurs no runtime overhead. Its primary utility lies in creating more generic and type-safe macros or function definitions, particularly in systems programming where type deduction is critical but C++11’s decltype might not be available or suitable for all contexts. While typeof offers significant flexibility for type deduction at compile-time, its non-standard nature means that code relying on it might not be portable across all C++ compilers. Developers should be mindful of this limitation, especially when targeting cross-platform environments.

One of the most common applications of typeof in GNU-specific codebases is within macros that need to declare variables of the same type as an input argument, without knowing that type beforehand. This can lead to highly efficient and type-correct low-level code. However, with the advent of C++11’s decltype and C++14’s return type deduction for functions, many of the use cases for typeof can now be addressed using standard C++ features, promoting greater code portability. More information on GNU extensions, including typeof, can often be found in GCC’s official documentation.

Key Distinctions and Use Cases ------------------------------

The core difference between typeid and typeof boils down to when and how they acquire type information. typeid operates at runtime, using RTTI to determine an object’s dynamic type, especially within polymorphic hierarchies. In contrast, typeof (a non-standard extension) works entirely at compile time, deducing the type of an expression without executing any code. This fundamental difference dictates their appropriate use cases and performance implications.

Featured Snippet: When choosing between typeid and typeof in C++, the primary consideration is whether you need to determine an object’s type at runtime (typeid, for polymorphic classes) or deduce an expression’s type at compile time (typeof, a GNU extension). typeid requires RTTI and introduces potential runtime overhead, while typeof offers zero runtime cost but sacrifices portability due to its non-standard nature, often superseded by standard C++ features like decltype for compile-time type deduction.

When to Use typeid (and When to Avoid It)

typeid is invaluable when you need to perform actions based on the actual, dynamic Question & Answer :

I am wondering what the difference is between typeid and typeof in C++. Here’s what I know:

  • typeid is mentioned in the documentation for type_info which is defined in the C++ header file typeinfo.
  • typeof is defined in the GCC extension for C and in the C++ Boost library.

Also, here is test code test that I’ve created where I’ve discovered that typeid does not return what I expected. Why?

main.cpp

#include <iostream> #include <typeinfo> //for 'typeid' to work class Person { public: // ... Person members ... virtual ~Person() {} }; class Employee : public Person { // ... Employee members ... }; int main () { Person person; Employee employee; Person *ptr = &employee; int t = 3; std::cout << typeid(t).name() << std::endl; std::cout << typeid(person).name() << std::endl; // Person (statically known at compile-time) std::cout << typeid(employee).name() << std::endl; // Employee (statically known at compile-time) std::cout << typeid(ptr).name() << std::endl; // Person * (statically known at compile-time) std::cout << typeid(*ptr).name() << std::endl; // Employee (looked up dynamically at run-time // because it is the dereference of a pointer // to a polymorphic class) } 

output:

bash-3.2$ g++ -Wall main.cpp -o main bash-3.2$ ./main i 6Person 8Employee P6Person 8Employee 

C++ language has no such thing as typeof. You must be looking at some compiler-specific extension. If you are talking about GCC’s typeof, then a similar feature is present in C++11 through the keyword decltype. Again, C++ has no such typeof keyword.

typeid is a C++ language operator which returns type identification information at run time. It basically returns a type_info object, which is equality-comparable with other type_info objects.

Note, that the only defined property of the returned type_info object has is its being equality- and non-equality-comparable, i.e. type_info objects describing different types shall compare non-equal, while type_info objects describing the same type have to compare equal. Everything else is implementation-defined. Methods that return various “names” are not guaranteed to return anything human-readable, and even not guaranteed to return anything at all.

Note also, that the above probably implies (although the standard doesn’t seem to mention it explicitly) that consecutive applications of typeid to the same type might return different type_info objects (which, of course, still have to compare equal).