Ch19: Legacy Exceptions and Herbceptions

中文(简体)

What This Chapter Is For

You have been throwing and catching since Ch3.16, and every page since then has used the same two statements. What you have not seen is the table behind the error value: the thing that decides what a code means, what it prints, and which ::std::errc it corresponds to. This chapter is about that table, and about the other exception mechanism C++ has, which you must be able to read and must not use.

Mechanism What it costs What it costs in this book
Herbceptions Two words on the return path plus one failure bit — the same shape as returning an error code The only mechanism used, everywhere
Legacy C++ exceptions A heap allocation per throw, a two-phase stack walk, frame tables in every function, a personality routine, RTTI for handler matching Read-only. Removed from every build by flag (Ch19.4)

The short version of the second row: legacy exceptions are not merely slow (about a microsecond per throw, measured in Ch19.8). They are unavailable on most targets you will ship to — freestanding, kernels, bootloaders, embedded boards, WebAssembly — because the unwinder, the loader registration and the __cxa_* runtime they depend on do not exist there.

How to Read This Chapter

Read 19.1 only when you are writing a library that has a code space of its own. Read it carefully anyway, because it starts with the recommendation that saves the most work: the domains in the runtime are meant to be reused, and one of them covers nearly everything.

Read 19.2 first: it decides what counts as an error at all, and everything else in the chapter follows from it. Then read 19.3, 19.4 and 19.5 as recognition training for the code you will inherit, and 19.6 as the two directions of the bridge you will need the day a dependency hands you a std::runtime_error. 19.7 is five flags to copy into your build right now.