4 ms·
Or just do it in C. #define span(T) struct span_##T { size_t len; T *data; } #define span_access(T, x, i) (*({ \ span(T) *_v = (x);
by uecker 8mo ago
Or just do it in C.
#define span(T) struct span_##T { size_t len; T *data; }
#define span_access(T, x, i) (*({ \
span(T) *_v = (x); \
auto _i = (i); \
if (((size_t)_i) >= _v->len) abort(); \
&_v->data[_i]; \
}))
https://godbolt.org/z/TvxseshGc https://godbolt.org/z/TvxseshGc
- nananana9 8mo agoStill requires a gcc/clang specific extension (although this one I'd be very happy to see standardized)
- uecker 8mo agoOnly statement expressions, but one can also implement this without them.
- nananana9 8mo agoStill, please standardize them :). I don't use much C but if you add them to the standard they'll probably trickle down to C++ compilers by 2045 and I'll have a good 10 years to use them before I retire.
- uecker 8mo agoYou are not happy with immediately invoked lambda expressions?
- nananana9 8mo agoWell, I'll take them over the nothing you're giving me :D But in all seriousness, I want this: struct Result { int value; int err; }; #define TRY(res) \ ({ \ Result _res = res; \ if (failed(res)) return res; \ res.value; \ }) Result f1(...) { ... } Result f2() { int res = TRY(f1(...)); // <<<< ... return success(); } Can't be done with lambdas since the macro needs to return out of the actual function, not the lambda. Pretty much rust question mark, but without rust, or zig "try" but without zig.
- uecker 8mo agoI see, thanks! There is general consensus that statement expressions should become part of ISO C, but some lack of time to get it done. I am not part of WG21 though, so can't say anything about C++.
- fuhsnn 8mo agoThe fact that pointer types can't be used with this pattern without typedef still seems kinda primitive to me.
- uecker 8mo agoYou can use pointer types by using a typedef first, but I agree this not nice (I hope we will fix this in future C). But then, I think this is a minor inconvenience for having an otherwise working span type in C.