Date: Sat, 29 Aug 2026 08:00:06 +0200
> On Aug 28, 2026, at 8:02 PM, Marcin Jaczewski via Std-Proposals <std-proposals_at_[hidden]> wrote:
>
> pt., 28 sie 2026 o 18:33 Tiago Freire via Std-Proposals
> <std-proposals_at_[hidden]> napisał(a):
>>> 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();
For this we already have std::expected. I personally started using it together with std::error_code as error type. If all libraries use this it is really easy to glue everything together. However, it is the opposite of your expected_variant; just like exceptions this hides which specific errors could be returned. BTW, even though the error type would be std::error_code, you would check against std::error_conditions. You would only handle the errors you would expect and explicitly pass through all other errors. Making this explicit makes you think more about what happens if you don’t handle the error. Making the std::expected return type [[nodiscard]] also forces you handle the error everywhere (or ignore it explicitly).
> ```
>
> That have exactly same problems as
>
> ```
> int Foo() throw(ErrorA, ErrorB, ErrorC);
> ```
Instead of adding a new standard feature, I would hope that future versions of reflection would help you with this problem: I imagine that you could add annotations to your function specifying which exceptions can be thrown. Then you add a consteval function at the bottom of each implementation file that goes through all function definitions of the current translation unit and analyzes their bodies and derives if the exception specification holds. We are not there yet because this requires to be able to reflect over the expressions of a function body line by line.
>
>
> pt., 28 sie 2026 o 18:33 Tiago Freire via Std-Proposals
> <std-proposals_at_[hidden]> napisał(a):
>>> 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();
For this we already have std::expected. I personally started using it together with std::error_code as error type. If all libraries use this it is really easy to glue everything together. However, it is the opposite of your expected_variant; just like exceptions this hides which specific errors could be returned. BTW, even though the error type would be std::error_code, you would check against std::error_conditions. You would only handle the errors you would expect and explicitly pass through all other errors. Making this explicit makes you think more about what happens if you don’t handle the error. Making the std::expected return type [[nodiscard]] also forces you handle the error everywhere (or ignore it explicitly).
> ```
>
> That have exactly same problems as
>
> ```
> int Foo() throw(ErrorA, ErrorB, ErrorC);
> ```
Instead of adding a new standard feature, I would hope that future versions of reflection would help you with this problem: I imagine that you could add annotations to your function specifying which exceptions can be thrown. Then you add a consteval function at the bottom of each implementation file that goes through all function definitions of the current translation unit and analyzes their bodies and derives if the exception specification holds. We are not there yet because this requires to be able to reflect over the expressions of a function body line by line.
>
Received on 2026-08-29 06:00:26
