Date: Fri, 28 Aug 2026 20:02:16 +0200
pt., 28 sie 2026 o 18:33 Tiago Freire via Std-Proposals
<std-proposals_at_[hidden]> napisaĆ(a):
>
> > the real problem is as soon as you make that change you have often thousands of functions that cascading need to change because now you changed your interface.
>
> Yes, but isn't that just the symptom of a much larger problem.
> You haven't as much provided a useful function as you have provided a means for your application to ungracefully terminate if you don't document that your code can throw, what it can throw and how you can recover if a function does throw. I.e. you just gave everyone a loaded foot gun.
>
> If you state that your function can throw A, B, and C I can write a catch clause to catch A, B, and C and *handle the error*.
> But now you if you make a change and it can also throw D, the fact that this cascades trough out your entire code base is a good thing.
> You have changed the contract of what the function can do, code that was previously safe now isn't, and if the caller doesn't catch it you have also changed the caller's contract, then the caller of the caller will throw an additional exception as well.
>
If a function already throws an exception, does this matter what new
type it throws for the whole call stack?
Only place where it matters is the place where you handle this new
exception, rest code should stay agnostic to this new error case.
> Exceptions are evil because it changes code upstream instead of downstream.
>
Error codes are the same, if you need to add failable operation to any
function you need to add propagation of failure upstream.
If the function returns `void` you need to change it to return some
error code. If it's already return some error code you need extend it
to add
new value and handle it upstream. Even better if you have robust error
codes of 20 diffrent values and add some C code that has its own error
codes how do you map both? Do you glue them together? Even is only
place where this can happen?
Only way to handle it generally is code like:
```
expected_variant<int, ErrorA, ErrorB, ErrorC> Foo();
```
That have exactly same problems as
```
int Foo() throw(ErrorA, ErrorB, ErrorC);
```
> The fact that you have to deal with changing code in a thousand different places throughout the code base, is a small mercy that allows you the opportunity to at least validate if code upstream was able to handle it.
> Make that change silent and you have not fixed the problem, you just hid it and don't realize you created a problem, now you have thousands of different bugs with a single code change.
>
> That's why I'm in the camp "No exceptions" please!
>
> -----Original Message-----
> From: Henry Miller <hank_at_[hidden]>
> Sent: Friday, August 28, 2026 14:21
> To: Henry Miller via Std-Proposals <std-proposals_at_[hidden]>
> Cc: Tiago Freire <tmiguelf_at_[hidden]>; Zamfir Yonchev <zamfir.yonchev_at_[hidden]>
> Subject: Re: [std-proposals] fine-control exception/error/UB handling on function boundary
>
>
> On Fri, Aug 28, 2026, at 03:38, Tiago Freire via Std-Proposals wrote:
>
> > And I would kill to be able to specify a list of possible exceptions
> > at the interference level to be able to validate the code is exception
> > safe.
> >
>
> A number of languages have tried that in the past and books have always quickly come up and said, never specify the exact exceptions except on a very generic level. That is, you say, 'throws anything' in whatever the language syntax specifies that as. Too many times you want to make a slight change to implementation and discover that it would really be helpful to throw a different exception in some situation. Often some users are demanding a specific bit of information that they would catch and handle differently. the real problem is as soon as you make that change you have often thousands of functions that cascading need to change because now you changed your interface. You can throw a clang tidy at the problem but that's not going to tell you the place where you should catch the exception in cases where you don't want to cascade it all the way and so it's a question of valuable even with modern tools.
>
> Now in C++ it would be useful to say throws std::exception, that is I won't throw an int or any other type that is not derived from standard exception. This is good practice anyway. It might be useful to also say, we'll not throw std::bad_alloc or something like that, where you can say a whole class of things would not be thrown.
>
> Though I'm not sure if there's any advantage to putting the above into the language versus putting it into something like the doxygen comments. I'm not sure if the compilers can use it and so long as the information of what your wheeler will throw is in place, static analysis can find it, that's probably good enough for your needs.
>
> however specific list of exceptions that a function will throw is always going to be listed in every intelligent style guide we will not use this
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
<std-proposals_at_[hidden]> napisaĆ(a):
>
> > the real problem is as soon as you make that change you have often thousands of functions that cascading need to change because now you changed your interface.
>
> Yes, but isn't that just the symptom of a much larger problem.
> You haven't as much provided a useful function as you have provided a means for your application to ungracefully terminate if you don't document that your code can throw, what it can throw and how you can recover if a function does throw. I.e. you just gave everyone a loaded foot gun.
>
> If you state that your function can throw A, B, and C I can write a catch clause to catch A, B, and C and *handle the error*.
> But now you if you make a change and it can also throw D, the fact that this cascades trough out your entire code base is a good thing.
> You have changed the contract of what the function can do, code that was previously safe now isn't, and if the caller doesn't catch it you have also changed the caller's contract, then the caller of the caller will throw an additional exception as well.
>
If a function already throws an exception, does this matter what new
type it throws for the whole call stack?
Only place where it matters is the place where you handle this new
exception, rest code should stay agnostic to this new error case.
> Exceptions are evil because it changes code upstream instead of downstream.
>
Error codes are the same, if you need to add failable operation to any
function you need to add propagation of failure upstream.
If the function returns `void` you need to change it to return some
error code. If it's already return some error code you need extend it
to add
new value and handle it upstream. Even better if you have robust error
codes of 20 diffrent values and add some C code that has its own error
codes how do you map both? Do you glue them together? Even is only
place where this can happen?
Only way to handle it generally is code like:
```
expected_variant<int, ErrorA, ErrorB, ErrorC> Foo();
```
That have exactly same problems as
```
int Foo() throw(ErrorA, ErrorB, ErrorC);
```
> The fact that you have to deal with changing code in a thousand different places throughout the code base, is a small mercy that allows you the opportunity to at least validate if code upstream was able to handle it.
> Make that change silent and you have not fixed the problem, you just hid it and don't realize you created a problem, now you have thousands of different bugs with a single code change.
>
> That's why I'm in the camp "No exceptions" please!
>
> -----Original Message-----
> From: Henry Miller <hank_at_[hidden]>
> Sent: Friday, August 28, 2026 14:21
> To: Henry Miller via Std-Proposals <std-proposals_at_[hidden]>
> Cc: Tiago Freire <tmiguelf_at_[hidden]>; Zamfir Yonchev <zamfir.yonchev_at_[hidden]>
> Subject: Re: [std-proposals] fine-control exception/error/UB handling on function boundary
>
>
> On Fri, Aug 28, 2026, at 03:38, Tiago Freire via Std-Proposals wrote:
>
> > And I would kill to be able to specify a list of possible exceptions
> > at the interference level to be able to validate the code is exception
> > safe.
> >
>
> A number of languages have tried that in the past and books have always quickly come up and said, never specify the exact exceptions except on a very generic level. That is, you say, 'throws anything' in whatever the language syntax specifies that as. Too many times you want to make a slight change to implementation and discover that it would really be helpful to throw a different exception in some situation. Often some users are demanding a specific bit of information that they would catch and handle differently. the real problem is as soon as you make that change you have often thousands of functions that cascading need to change because now you changed your interface. You can throw a clang tidy at the problem but that's not going to tell you the place where you should catch the exception in cases where you don't want to cascade it all the way and so it's a question of valuable even with modern tools.
>
> Now in C++ it would be useful to say throws std::exception, that is I won't throw an int or any other type that is not derived from standard exception. This is good practice anyway. It might be useful to also say, we'll not throw std::bad_alloc or something like that, where you can say a whole class of things would not be thrown.
>
> Though I'm not sure if there's any advantage to putting the above into the language versus putting it into something like the doxygen comments. I'm not sure if the compilers can use it and so long as the information of what your wheeler will throw is in place, static analysis can find it, that's probably good enough for your needs.
>
> however specific list of exceptions that a function will throw is always going to be listed in every intelligent style guide we will not use this
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2026-08-28 18:02:35
