Remix.run Logo
thomasmg 2 hours ago

I don't have a strong opinion what is better in this case, but my view is:

> document and express intent clearly

Arguably, the void* does that as well?

> Any seasoned C++ developer seeing this knows what this reinterpret_cast means.

Same for void*?

> it's a bit more text to read

If you have to call it many times, this adds up.

> Some might also say it complexifies and uglifies the code

I think the point is that it adds security, which the other options don't. And, it doesn't add complexity on the caller, but only at one place: the implementation.

> makes it non-portable on top of that.

This can be solved.

stinos 10 minutes ago | parent [-]

> Arguably, the void* does that as well?

Sort of (I mean: seeing void* and a size probably means 'arbitrary sequence of bytes' or something like that, but well it's void* so it can be like anything whereas with std::span you get more of a hint what's going on just based on the type), but not at the callsite which is what the author is referring to when it's about reinterpret_cast.

> I think the point is that it adds security, which the other options don't

Imo span also does that to some extent, but already when writing the code and not afterwards in e.g. static analysis. E.g. if I get an std:span<const char> I'd have to do counterintuitive things to misuse it. Annotating a void* still leaves it a void* which I then need to cast to char* if I think that's what it is intended.

Don't get me wrong: I've written my fair share of void* but these days I really feel like there's almost always a better thing which can be used instead. Though I do admit that since I've written and consumed a lot of code with such alternatives I'm not hindered by readability/apparent complexity of it anymore but I understand that's not the same for everyone.