Nearby lessons
113 of 124C - register Storage Class
register asks the compiler to keep a variable in a CPU register instead of memory. Learn what registers are, the one rule the keyword actually enforces, and why modern optimisers made it obsolete.
What a Register Is
| Storage | Typical access time | Capacity |
|---|---|---|
| CPU register | Under 1 cycle | ~16 slots |
| L1 cache | ~4 cycles | Tens of KB |
| L2 / L3 cache | ~12–40 cycles | MB |
| Main memory (RAM) | ~200 cycles | GB |
It Is Only a Hint
The compiler is free to ignore register entirely, and modern ones almost always do — they run their own register allocator:
The One Rule That Is Enforced
register variable. This is not a hint — it is a hard compile error, because a register has no memory address to take. It is the only observable effect the keyword reliably has, and it is what makes register useless for arrays: you can never index one without an address.Where It Can Be Used
register applies only to local variables and function parameters — never to globals or static variables, which by definition live in memory:
The Historical Use Case
In the 1970s and 80s compilers did little optimisation, so hinting the hot loop counter genuinely helped. This is the pattern you will see in old code:
Why Compilers Outperform the Hint
Register allocation is a global optimisation problem. The compiler sees the whole function; you see one declaration:
| The compiler knows | You are guessing |
|---|---|
| How often each variable is actually used | Which one feels hottest |
| Exact live ranges, so registers can be reused | That the variable exists |
| The real register count of the target CPU | Roughly 16, maybe |
| Which values must spill and when | Nothing |
| How inlining changes the picture | Nothing |
register vs the Other Storage Classes
It behaves exactly like auto apart from the address restriction:
register | auto | static | |
|---|---|---|---|
| Stored in | Register (if honoured) | Stack | Data segment |
| Lifetime | The block | The block | Whole program |
| Default value | Garbage | Garbage | Zero |
& allowed | No | Yes | Yes |
| Valid at file scope | No | No | Yes |
How to Actually Make Code Faster
If you reach for register because a loop is slow, these are the things that will genuinely help:
Its Status Today
Still valid C, still useless in practice. C++17 removed it as a storage class entirely:
| Language | Status |
|---|---|
| C89 – C23 | Valid, but ignored as a hint by every mainstream compiler |
| C++98 – C++14 | Valid, deprecated in C++11 |
| C++17 and later | Removed — the keyword is reserved but unusable |
register to read old code and to answer the interview question, not to write it. It is the clearest example in C of an optimisation that made sense for the hardware and compilers of its era and stopped making sense once optimisers got good.Common Mistakes
- Taking the address —
®isterVaris a hard compile error. - Expecting a guarantee — it is a hint the compiler may ignore.
- Using it at file scope — only locals and parameters are allowed.
- Combining it with
static— a variable cannot have two storage classes. - Declaring a
registerarray — indexing needs an address, so it is unusable. - Expecting a speed-up — measure; you will find none.
- Sprinkling it everywhere — the extras are silently ignored and the code just reads worse.
- register requests storage in a CPU register — the compiler may refuse.
- You cannot take the address of a register variable; that rule IS enforced.
- Only usable on local variables and function parameters.
- Modern optimisers allocate registers better than any human hint.
- It is deprecated in C++17 and effectively obsolete in C.