abseil / abseil/abseil-cpp

Throwing callback leads to program terminations in absl::Cleanup

Aperta
#1,238 1 commento 0 reazioni 0 assegnatari Vedi su GitHub
bug
Lingua principale
C++
Stelle
18.1k
Fork
3.2k
Merge medio
20h 36m
PR unite (30g)
1

Descrizione

**Describe the bug**
Let `Callback` be a type, whose `operator()` is `noexcept(false)` and actually throws.
When an object of such a type is passed as the callback for `absl::Cleanup`, then the destructor `~Cleanup` will always abort the program at runtime, because it is (implicitly) `noexcept`.

I would expect one of the following two possibilities:
- The program doesn't compile, because `Cleanup` `static_assert`s that the callback type is `nothrow_invocable`.
- The destructor propagates the exception (this would require marking it `noexcept(std::is_nothrow_invocable_v)`.

**Steps to reproduce the bug**
Consider the following minimal example:
```
#include
int main() {
try {
absl::Cleanup cl{[]() {throw 42;}};
} catch(...) {}
}
```
[Link to godbolt](https://godbolt.org/z/9cz1K4fTf)

**What system are you using**
I am using Ubuntu 22.04 and G++ 11.1, but the behavior should be the same on
any standard-conforming compiler and platform.

**Additional context**
I am aware that "throwing destructors" are a somewhat controversial topic. Maybe a compromise would be, to `static_assert` as a default, but to provide a possibility to opt out of that assertion, e.g.:

```
absl::Cleanup cl{[]() noexcept {}}; // Fine
absl::Cleanup cl2{[]() {throw 42;}}; // Assertion failure, not noexcept
absl::Cleanup cl3{[]() {throw 42;}}; // Fine
```

I am willing to provide an implementation as soon as we have discussed, what the desired behavior should be.

A problem might be, that the "safer" suggestions (involving the `static_assert`) are a breaking change for callback types that do not throw, but are not explicitly marked `noexcept`.

Best regards
Johannes

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.