abseil-cpp
abseil-cpp copied to clipboard
Do you have plans to release macros accompanying Status and StatusOr?
There are useful macros that can accompany Status and StatusOr, like RETURN_EARLY_IF_ERROR() or ASSIGN_VALUE_OR_RETURN().
Are there any plans of open sourcing such macros?
No one is actively working on this, but we will likely consider it in the future. Don't expect it for at least a year.
The idea of releasing the macros is going to be a contentious issue. Many of us think the use of these macros is not good programming practice, and would prefer that you write the equivalent C++ directly. The counter argument is that some people prefer the more concise style, and providing the macros would allow having a single, consistent, and robust implementation.
On the off chance that balance of opinion might help, I'd be strongly in favour of releasing the macros. Writing the boilerplate over and over to handle and return Status errors, or extract values from StatusOr is tedious and error prone. For myself, I find code using the macros to be much more readable, and it encourages me to make more of my functions return Status/StatusOr, instead of more opaque failure values like empty strings, null pointers, -1, false, and so on.
I would second this opinion. A lot of status checking is really repetitive and is essentially boilerplate. Rather than everyone trying to make their own macros to make their code concise, perhaps it would help exposing some of the basic macros that you already have. I held a pretty positive opinion of them when I was at Google. Perhaps a discussion should be around what a more idiomatic approach could be to replacing these macros, if they aren't good C++ style. If I have to write 4 lines of boilerplate vs one line, I'd rather do the latter.
If you want to use an implementation in the meantime, there are a ton of copies of these macros floating around:
https://github.com/search?l=C%2B%2B&q=org%3Agoogle+%22%23define+ASSIGN_OR_RETURN%22&type=Code https://github.com/search?q=org%3Agoogle+%22%23define+RETURN_IF_ERROR%22&type=Code
The good ones for ASSIGN_OR_RETURN let you declare variables on the left hand side, like this:
ASSIGN_OR_RETURN(FILE* f, Open("foo.txt"))
I think having at least RETURN_IF_ERROR
and ASSIGN_OR_RETURN
macros in the public API would be beneficial IMO.
A workaround for ones who desperately need them :)
// Run a command that returns a absl::Status. If the called code returns an
// error status, return that status up out of this method too.
//
// Example:
// RETURN_IF_ERROR(DoThings(4));
#define RETURN_IF_ERROR(expr) \
do { \
/* Using _status below to avoid capture problems if expr is "status". */ \
const absl::Status _status = (expr); \
if (_PREDICT_FALSE(!_status.ok())) return _status; \
} while (0)
// Run a command that returns a absl::StatusOr<T>. If the called code returns
// an error status, return that status up out of this method too.
//
// Example:
// ASSIGN_OR_RETURN(auto value, MaybeGetValue(arg));
#define ASSIGN_OR_RETURN(...) \
STATUS_MACROS_IMPL_GET_VARIADIC_( \
(__VA_ARGS__, STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_2_)) \
(__VA_ARGS__)
// =================================================================
// == Implementation details, do not rely on anything below here. ==
// =================================================================
#define STATUS_MACROS_IMPL_GET_VARIADIC_HELPER_(_1, _2, NAME, ...) NAME
#define STATUS_MACROS_IMPL_GET_VARIADIC_(args) \
STATUS_MACROS_IMPL_GET_VARIADIC_HELPER_ args
#define STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_2_(lhs, rexpr) \
STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_( \
STATUS_MACROS_IMPL_CONCAT_(_status_or_value, __LINE__), lhs, rexpr, \
return std::move(STATUS_MACROS_IMPL_CONCAT_(_status_or_value, __LINE__)) \
.status())
#define STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_(statusor, lhs, rexpr, \
error_expression) \
auto statusor = (rexpr); \
if (_PREDICT_FALSE(!statusor.ok())) { \
error_expression; \
} \
lhs = std::move(statusor).value()
// Internal helper for concatenating macro values.
#define STATUS_MACROS_IMPL_CONCAT_INNER_(x, y) x##y
#define STATUS_MACROS_IMPL_CONCAT_(x, y) STATUS_MACROS_IMPL_CONCAT_INNER_(x, y)
// Internal helper for stringifying macro values.
#define _PREDICT_FALSE(x) (__builtin_expect(false || (x), false))
Any chance of an update on the status (hah) of potentially publishing these macros?
Any chance of an update on the status (hah) of potentially publishing these macros?
This issue was recently assigned to someone, so hopefully this will happen.
These are easy to add and more ergonomic than RETURN_IF_ERROR, etc.
#define TRY(...) \
({ \
auto res = (__VA_ARGS__); \
if (!res.ok()) return std::move(res).status(); \
std::move(*res); \
})
#define TRYV(...) \
do { \
auto res = (__VA_ARGS__); \
if (!res.ok()) return res; \
} while (false)
Usage from a function that returns Status
or StatusOr<T>
:
StatusOr<int> X();
StatusOr<int> Y();
Status Z();
StatusOr<int> Add(int x, int y) {
TRYV(Z());
return TRY(X()) + TRY(Y());
}