This is not true for a variety of reasons, but the main ones are maybe missed optimizations and otherwise-unnecessary spills of objects into memory so that their destructors may be called.
> Also in C++ you have operators that are integrated in the type system and are resolved at compile-time to know whether an given expression can throw an exception or not.
Maybe if you only have a single TU or LTO? In general any function from another TU can throw an exception so you don't have this.
The missed optimization opportunity you describe only affects the Windows ABI, designed in 1989.
> Maybe if you only have a single TU or LTO?
Whether a function can throw or not is part of its signature.
But with decades gone, things changed. That constant costs is relatively not so small anymore, and those branches are much cheaper now.
Oh yes, there is. C++ compiler has to emit unwind tables, register destructors for RAII resources and generate the RTTI information (where applicable).
In this trivial example, consider and compare two versions, the first does not have an exception handler, the second one wrap a single constructor call with a dummy try/catch block:
– No exception handling: https://godbolt.org/z/MK1bof45d
vs
– With a dummy try/catch block: https://godbolt.org/z/hT4Efez1h
For the latter one, the object file size is up by 1kB instantly by virtue of adding a no-op exception handler. Exception handling implementation is not standardised and varies across different compilers AND also across different runtimes. Due to space constraints, the C++ exceptions are oftentimes a big no-no in the embedded world due to the space and time cost the language imposes. As well as long gone are the days when a «try» was a «setjmp» plus a few bells and whistles and «throw ecx;» was a «longjmp».
On the contrary, the approach you describe introduce a lot of overhead, since it affects all code paths, the function call ABI, jumps after every function call etc.
Also in C++ you have operators that are integrated in the type system and are resolved at compile-time to know whether an given expression can throw an exception or not. Do not confuse C++ with Java.