https://github.com/nobodyxu/return-exception
Return errors in an unignorable way like exceptions, but with -fno-exceptions support.
https://github.com/nobodyxu/return-exception
cpp error-handling
Last synced: over 1 year ago
JSON representation
Return errors in an unignorable way like exceptions, but with -fno-exceptions support.
- Host: GitHub
- URL: https://github.com/nobodyxu/return-exception
- Owner: NobodyXu
- License: mit
- Created: 2020-06-30T11:06:57.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2020-07-23T09:46:27.000Z (almost 6 years ago)
- Last Synced: 2025-03-25T02:17:39.369Z (over 1 year ago)
- Topics: cpp, error-handling
- Language: C++
- Homepage:
- Size: 498 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# return-exception
Return errors in an unignorable way and have compile-time only Catch, which produces no bloat code with `CXXFLAGS=-O2 -Wl,--strip-all`.
[Document]
## Advantage compared to C++ exception
- Pay for what you use -- only when you use a specific feature will that code be generated.
- No rtti is required -- `variant` is used for minimal runtime check per-`Ret_except`, only generate
when required and will not add a lot of global information.
- You can use any `variant` implementation in `Ret_except`, giving you further control of the
generated code.
- All generated code will undergo optimizer, which can heavily optimize to remove any bloat code with
`CXXFLAGS=-O2 -Wl,--strip-all`.
- More explicit syntax: `Ret_except` requires all possible exception type to be provided at compile-time.
- If you don't handle the exception stored in `Ret_except`, then it will terminate your program by
- Calling `errx` and print `e.what()` (if `e.what()` is valid) if exception is disabled.
- Otherwise, throw exception again.
## Downsides compared to C++ exceptions
- Hard or impossible to use in constructor.
- Since all possible exception type is explicit, it poses a big problem in template code:
You would have to use detect return type of function and use `glue_ret_except_from_t` to add more
exceptions.
For more information, check [Document].
## Usage
```c++
#include "/path/to/ret-exception.hpp"
#include
#include
#include
#include
#include
#include
template
auto ftoi(long double f) noexcept -> Ret_except
{
if (f == std::numeric_limits::infinity())
return {std::invalid_argument{"f should not be INF"}};
else if (f > std::numeric_limits::max())
return {std::out_of_range("f is too large")};
else if (f < std::numeric_limits::min())
return {std::out_of_range("f is too small")};
return static_cast(f);
}
int main(int argc, char* argv[])
{
long double f;
std::scanf("%Lf", &f);
auto integer = ftoi(f)
.Catch([](const std::out_of_range &e) noexcept {
// Catch out_of_range only
errx(1, "std::out_of_range: %s", e.what());
}).Catch([](const auto &e) noexcept {
// Catch any exception
errx(1, "In function %s: Catched exception %s",
__PRETTY_FUNCTION__, e.what());
}).get_return_value(); /* Get return value here when all exceptions are handled */
std::printf("%" PRIu64 "\n", integer);
return 0;
}
```
Now, if you compile the code with `clang++ -std=c++17 -O2 -Wl,--strip-all -fno-exceptions -fno-rtti example.cc`,
you will get an executable that is fairly small (on my x86-64 intel machine, 12K only).
Let's do some test on the code:
```
$ ./a.out
1.2333
1
$ ./a.out
123412434324823878712471230712847312844
a.out: std::out_of_range: f is too large
$ ./a.out
INF
a.out: In function auto main(int, char **)::(anonymous class)::operator()(const auto &) const [e:auto = std::invali
d_argument]: Catched exception f should not be INF
```
It's doing exactly what we want it to do.
What is more amazing is that how small the executable can be.
If you run the compiler again with
`clang++ -std=c++17 -O3 -flto -Wl,--strip-all -fno-exceptions -fno-rtti example.cc`, you would probably find
the executable to be even smaller.
On my machine, I found it to be merely 8.9K, which definitely is not possible with c++ exceptions.
For more information, check [Document].
[Document]: https://nobodyxu.github.io/return-exception/