6

voidify() is used in various constructors in specialized.algorithms that were introduced in c++20. It isn't clear to me what it's supposed to do. It's given as:

template<class T>
constexpr void* voidify(T& obj) noexcept {
    return const_cast<void*>(static_cast<const volatile void*>(addressof(obj)));
}

What is the reason for casting an address into a pointer to a const volatile void, and then back into just a pointer to a void?

I'm guessing that it has something to do with telling the compiler's optimizer, somehow, that an object assigned to the memory it ultimately addresses should toss out all prior cache (read or writes) that it knows about. But I can't find any description anywhere of how this is supposed to work.

Note: This question is neither the same as the related, but different question here, not does that answer address this question.

That question was why one couldn't simply use static_cast<void*> and the answer was the obviously correct one that static_cast is not allowed to cast away const but can add cv's.

doug
  • 3,840
  • 1
  • 14
  • 18
  • 3
    Related: [What is the purpose for std::construct_at to cast through a pointer to volatile when using placement new?](https://stackoverflow.com/questions/63325244/) – Remy Lebeau May 17 '22 at 22:15
  • @RemyLebeau Yes, it's related but quite a different question and the answer doesn't address why the original part of the cast was `static_cast(p)` – doug May 18 '22 at 02:26
  • Did this answer you? https://stackoverflow.com/questions/38193861/the-advantage-cast-pointer-to-void-when-use-new – 康桓瑋 May 18 '22 at 02:27
  • @康桓瑋 Not really. It doesn't address the purpose of first casting the address to a `volatile const*` Seems quite odd. Perhaps it is some sort of thing compiler writers can use to identify stuff that shouldn't be optimized. That's the general use of volatile. But then why then remove the cv's? It's as if the first cast somehow sticks. – doug May 18 '22 at 02:39
  • Didn't you already answer yourself in the OP? “*That question was why one couldn't simply use static_cast and the answer was the obviously correct one that static_cast is not allowed to cast away const but can add cv's.*” – 康桓瑋 May 18 '22 at 02:42
  • @康桓瑋 That question was why not use `static_cast` to a void ptr directly Clearly you must use `const_cast` to remove cv's. But what is the purpose of first casting to `volatile const *`? – doug May 18 '22 at 02:48
  • @doug "*the answer doesn't address why the original part of the cast was `static_cast(p)`*" - are you sure? Seemed pretty clearly stated: "*`T` ... may have cv-qualifiers... `static_cast` may not cast away constness. But `static_cast` may add cv-qualifiers. So in order to be generic ... static casts to the most cv-qualified version of a `void` pointer, and then removes those qualifiers.*" – Remy Lebeau May 18 '22 at 02:50
  • @RemyLebeau So this is some kind of workaround that legally allows one to cast away const? I've tried that using `constexpr` and it produced a compile error. I assume the library has some dispensation but what is that `volatile` thing? My speculation is it's related to optimization but i'd like some actual knowledge about why it's used in voidify. – doug May 18 '22 at 02:53
  • @doug [cv (const and volatile) type qualifiers](https://en.cppreference.com/w/cpp/language/cv) – Remy Lebeau May 18 '22 at 03:02
  • @RemyLebeau I understand what a const volatile object is. And I know a static cast can add cv's. But what is the effect of adding the cv's with a static cast then removing them with a const cast? And to a void* at that. I haven't found anything in the standard that explains what that is supposed to accomplish. – doug May 18 '22 at 03:10
  • @doug `placement-new` wants a non-cv-qualified `void*`, so that is what `voidify()` returns. But the object being voidified may or may not be cv-qualified. `static_cast` can't remove cv qualifiers, but it can add them. `const_cast` can remove them, *but they have to exist to begin with*. So the `static_cast` adds any cv qualifiers that may be missing, and then the `const_cast` removes them all. – Remy Lebeau May 18 '22 at 03:45
  • @RemyLebeau I think I get it. The problem is that static cast can cast to a void ptr but since it can't remove cv's, by adding both then it allows const cast to remove the cv's. It has to go this route because const cast can't cast to a different type so can't cast to a void ptr. Thanks. Not sure why I was so confused but I get it now. So just required to cast any possibly cv qualified ptr to a plain ptr to a void. – doug May 18 '22 at 04:13

0 Answers0