liveBook · Manning

Typeof operator

As explained in Modern C, Third Edition

typeof is a C type operator that derives a type from an expression or type name without evaluating an expression operand.

`typeof(3*x) y = 3*x;` declares `y` with the type of `3*x`, then initializes it with that expression. `typeof` supplies a type where a typedef name could otherwise appear; it does not evaluate its expression operand. The initializer is separate and does evaluate `3*x`. In unusual cases, this style can lead to an evaluation concern, so prefer `auto` for variable declarations. section 18.3.2

 #define static_assert_compatible(A, B, REASON)  \
   static_assert(_Generic((typeof(A)*)nullptr,   \
                          typeof(B)*: true,      \
                          default: false),       \
                 "expected compatible types: " REASON ", have " #A " and " #B "")

A type-compatibility macro uses `typeof(A)*` and `typeof(B)*` where `_Generic` needs types. The selection tests the pointer types without evaluating `A` or `B`. Its stated use is checking compatible non-array object types inside other macros. section 18.3.2

This is where `typeof` goes beyond `auto`: it can turn the type of a macro argument into a type name for a cast or generic selection. It can also help choose a function according to types derived from multiple arguments, or cast a generic operation’s result back to a type derived from its arguments. `typeof_unqual` is available when qualifiers must be handled differently. section 18.3.2 section 18.5

enum eInt : signed int { dInt = 0, uInt = 0xFFFF'FFFF, };
typedef enum eInt eInt;
enum eSig : typeof(4'294'967'295) { dSig = 0, uSig = 4'294'967'295, };
typedef enum eSig eSig;
enum e32 : uint32_t { d32 = 0, u32 = 0xFFFF'FFFF, };
typedef enum e32 e32;

An enumeration can use `typeof(4'294'967'295)` to specify that its underlying type is the type of this decimal constant, which is signed. This states a different intent from choosing `uint32_t` or relying on an ambiguous underlying type. section 5.6.2

TAKEAWAY: Use `auto` for ordinary inferred variable declarations. Reach for C23 `typeof` when a type derived from an expression must appear in a position that requires a type. section 18.3.2

How Modern C, Third Edition covers it

How deep it goes
Works through declarations and macro type matching, including evaluation and qualifier cautions, rather than detailing every typeof edge case.
Examples
Uses a declaration inferred from `3*x`, a static-assertion compatibility macro, and an enumeration typed from a decimal constant.
What it assumes
Assumes C expressions, declarations, and macros; places typeof after auto and _Generic in the type-generic programming progression.
What you can do after
Build it from scratch: use typeof with _Generic to check macro-argument types without evaluating the arguments.
How it connects
Connects typeof to auto, typedef, _Generic, typeof_unqual, macros, and enumeration underlying types.

Also explained in

Compare how 3 books explain typeof operator →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern C, Third Edition. The section links point to the parts of the book it draws on.