C++ Logo

std-proposals

Advanced search

Re: [std-proposals] template catch block

From: Andrey Semashev <andrey.semashev_at_[hidden]>
Date: Sat, 23 Sep 2023 14:44:41 +0300
On September 23, 2023 2:08:54 PM Frederick Virchanza Gotham via
Std-Proposals <std-proposals_at_[hidden]> wrote:

> Eight months ago I suggested on the mailing list here that Runtime
> Type Identification (RTTI) should be available inside a 'catch(...)'
> block, as I described in this paper:
>
> http://www.virjacode.com/download/RTTI_current_exception_latest.pdf
>
> Following on from that, I would like to propose the new idea of a
> 'template catch block'. Currently with C++23, we write try-catch as
> follows:
>
> try
> {
>
> }
> catch(std::exception const &e)
> {
>
> }
> catch(...)
> {
>
> }
>
> I propose that we can stick another catch-block between those two, as follows:
>
> try
> {
>
> }
> catch(std::exception const &e)
> {
>
> }
> template<typename T>
> catch(T &obj)
> {
> T tmp{};
> ++tmp;
> obj += tmp;
> SomeFunc(obj);
> }
> catch(...)
> {
>
> }
>
> Inside the second-last catch-block, the compiler has the RTTI of the
> thrown object at runtime, but at compile-time it has nothing. And so
> the only way the compiler could possibly implement the second-last
> catch-block as machine code would be to implement it in machine code
> for every intrinsic type, as well as for every user-defined type that
> has been seen so far in the translation unit, almost as though it had
> been written:
>
> try
> {
>
> }
> catch(std::exception const &e)
> {
>
> }
> catch(char &e)
> {
> char tmp{};
> ++tmp;
> obj += tmp;
> SomeFunc(obj);
> }
> catch(char signed &e)
> {
> char signed tmp{};
> ++tmp;
> obj += tmp;
> SomeFunc(obj);
> }
> catch(char unsigned &e)
> {
> char unsigned tmp{};
> ++tmp;
> obj += tmp;
> SomeFunc(obj);
> }
> catch(short &e)
> {
> short tmp{};
> ++tmp;
> obj += tmp;
> SomeFunc(obj);
> }
> catch(short unsigned &e)
> {
> short unsigned tmp{};
> ++tmp;
> obj += tmp;
> SomeFunc(obj);
> }
> catch(int &e)
> {
> int tmp{};
> ++tmp;
> obj += tmp;
> SomeFunc(obj);
> }
> catch(unsigned &e)
> {
> unsigned tmp{};
> ++tmp;
> obj += tmp;
> SomeFunc(obj);
> }
> catch(long &e)
> {
> long tmp{};
> ++tmp;
> obj += tmp;
> SomeFunc(obj);
> }
> catch(long unsigned &e)
> {
> long unsigned tmp{};
> ++tmp;
> obj += tmp;
> SomeFunc(obj);
> }
> // ......... and on and on and on for every type
> catch(...)
> {
>
> }
>
> If the catch-block were to fail to compile for any given type, then
> that implementation of the catch-block would be discarded (and so
> instead it will enter the 'catch(...)' block below it).
>
> Of course one of the drawbacks of this new proposed feature would be
> the bloat in size of machine code, but nowadays we have gigs of RAM
> and terras of disk space so it's not a big deal. This bloat in machine
> code size could be lessened by discarding the implementations that are
> identical -- for example on most computers the machine code
> implementations for 'signed long' and 'unsigned long' will be exactly
> the same (depending of course on a few things such as whether
> 'SomeFunc' is expanded inline and if the inline expansion is exactly
> the same for both types).
>
> Perhaps we could also put constraints on the catch-block:
>
> template<typename T>
> requires std::is_polymorphic_v<T>
> catch (T &obj)
> {
> T tmp{};
> ++tmp;
> obj += tmp;
> SomeFunc(obj);
> }
>
> If you were to ask me how this new feature would be useful, well
> here's one simple example:
>
> template<typename T>
> catch(T &obj)
> {
> cout << obj << endl;
> }
>
> Compiler vendors who implement this new feature could also use the
> same implementation to write an "std::visit" that can work with an
> "std::any" object, as follows:
>
> #include <any> // any
> #include <iostream> // cout, endl
> #include <vector> // vector
>
> using std::cout, std::endl;
>
> int main(void)
> {
> std::vector<std::any> vec = {1, 3.14, "hello"};
>
> for ( auto &e : vec )
> {
> std::visit([](auto &&arg){ cout << arg << endl; }, e);
> }
>
> return 0;
> }
>
> This new feature I'm proposing has many advantages, and only two disadvantages:
> (1) Bloat in size of machine code
> (2) Increase in compilation time
>
> Both of these disadvantages are mitigated on modern PC's with gigs of
> RAM and terras of space.

This is insane, you have no idea what you're talking about. No gigs of RAM
will save you in a moderately sized project with thousands of types, let
alone something like Chromium. Don't even get me started about how the
compiler is supposed to know every type in the program.

Received on 2023-09-23 11:44:47