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?

4
  • 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
    Commented Feb 20, 2011 at 15:40
  • 1
    I'm now curious into what led to this discovery. :) Playing with your compiler's intermediate output, are we?
    – user50049
    Commented Feb 20, 2011 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. Commented Feb 20, 2011 at 15:52
  • 2
    cdecl.org is useful for those occasional moments of asking "what does this qualifier apply to?" Commented Dec 12, 2013 at 17:36

2 Answers 2

51

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.

3
  • 2
    How useful is const void *? I can see how void * const could be, but not the former.
    – Spidey
    Commented Mar 20, 2012 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. Commented Mar 20, 2012 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". :) Commented Aug 9, 2018 at 15:43
16

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*.

1
  • hint: replace single quotes with backticks. Commented Nov 22, 2014 at 10:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.