67

Apparently, it is possible to declare a function returning const void:

const void foo()
{
}

g++ seems to consider the const important, because the following code does not compile:

#include <type_traits>

static_assert(std::is_same<void(), const void()>::value, "const matters");

So does const void have any practical significance?

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
  • 7
    Without knowing any specifics, I'd say that it's there for orthogonality reasons. Imagine a meta-function that takes the replaces the type, but not the qualifier. It would work with all types, except void if the void could implicitly be stripped away. – ltjax Feb 20 '11 at 15:40
  • 1
    I'm now curious into what led to this discovery. :) Playing with your compiler's intermediate output, are we? – Tim Post Feb 20 '11 at 15:49
  • @Tim: I was trying to decide where to put the `const` in a function pointer lookup table. There were three possible locations. One of them failed to compile, and the outermost `const` clearly declared an array of pointers to functions returning `const void`, and I was surprised the compiler accepted that code. – fredoverflow Feb 20 '11 at 15:52
  • 2
    cdecl.org is useful for those occasional moments of asking "what does this qualifier apply to?" – John Bartholomew Dec 12 '13 at 17:36

2 Answers2

50

Not really. But to ignore cv-qualifications on void or to make them errors could create unnecessary complexity in terms of both compiler implementation and end-user code. Consider templates like

  template<typename T>
  const T ...

There's no reason to make using void in that scenario a special case (more than it already is), it would just create headaches.

Also, while const void isn't helpful, const void* has its uses.

Logan Capaldo
  • 39,555
  • 5
  • 63
  • 78
  • 2
    How useful is const void *? I can see how void * const could be, but not the former. – Spidey Mar 20 '12 at 12:56
  • 6
    You can use it to preserve the (intended) const-ness when round tripping through `void*` land. `string read_name(enum dynamic_type, const void*)`. It's not super useful, no, but more so than `const void`. And of course `void* const` is useful but that's not really germane to the question. – Logan Capaldo Mar 20 '12 at 14:01
  • 1
    @Spidey If you're already doing stuff like hacking pointers (some `T*`) into `void*` (and back again later), then `const void*` is the `const` equivalent (so for some `const T*`). Sure, you could `const_cast` it away but why? In other words, it's precisely as useful as any other `const T*` and that's "quite a lot". :) – Lightness Races in Orbit Aug 09 '18 at 15:43
15

const void is allowed simply because there is no point making the compiler kick out this one exception to a general rule and it does no harm to leave it in.

There is some discussion above that const void* is not very useful:

How useful is const void *? I can see how void * const could be, but not the former. –Spidey

In fact const void* is sometimes essential. It declares that the thing being pointed to is read only as opposed to void* const which only declares that the pointer itself is constant but not the thing it points to.

From my experience, the pointer to constant using const void* is the more useful of the two forms. Of course, there is also const void* const meaning that both the pointer and the thing it points to are constant.

void* is normally used as a way to pass non-specific pointers around (e.g. with memcpy()). If you want to pass a const char* to such a function then you cannot use void* or you lose the fact that the thing it points to is constant and cannot be altered. Current C++ compilers will refuse to compile that as it would have to implicitly cast the const away, and rightfully so as this data might be in read-only memory and possibly cause an exception if anything tries to write to it.

This is why the second argument to memcpy() is const void* and not simply void*.

Ben N
  • 2,883
  • 4
  • 26
  • 49
Sie Raybould
  • 241
  • 3
  • 5