2

Basically I am wondering whether something like

f(const void* a){
  // This is also what `(char**) a` would do behind the scenes
  char** string_a_ptr {reinterpret_cast<char**>(const_cast<void*>(a))}; 

  // ...

is possible while preserving the const qualifier.

My question came up during an exercise about C-Arrays in C++. Because of C, I had to pass a function pointer with const void* arguments. In this case it was pointing on an array of C-strings. To cast it to the correct type I had to cast the const away. Is there a way in C++ to get something like a "(const char*)*"` pointer?

I have tried out const char** (without the const_cast) which yields

reinterpret_cast from type ‘const void*’ to type ‘const char**’ casts away qualifiers

and (const*)*, which gives a syntax error

expected type-specifier before ‘(’ token

This is a purely academic question. I am aware, that the problem can be solved easier and saver using std::string and #include <algorithm>.

While I am at it, are there advantages of sometimes using C-constructions in C++ or should they always be avoided if possible? I only did some small scale exercise problems with C code in C++, but it already causes quite a few headaches and forces me to look really closely under the hood, even though I have written a fair amount of C code in my life. Or is it would you rather recommend using the extern C qualifier and writing C code in pure C?

3
  • 1
    const void* would be char* const*. (It’s more obvious if you position the const qualifier consistently: void const*.) Commented Feb 2, 2017 at 7:21
  • I understand. Rewriting this as void const* is exactly what solves my confusion. Thanks! Commented Feb 2, 2017 at 7:33
  • 1
    "are there advantages of sometimes using C-constructions in C++" Yes. But you should always try to avoid them and know how much the C construct is costing you in readability, type-correctness or maintainability. In case of a void*that's all three of them you lose on. Commented Feb 2, 2017 at 9:28

2 Answers 2

4

That would be a char* const *.

There are three places in a double pointer to put const:

const char**

Pointer, to a pointer, to a character you cannot change.

char *const *

pointer, to a pointer you cannot change, to a character.

char ** const

pointer you cannot change, to a pointer, to a character.

You can mix these to make different parts const.

Sign up to request clarification or add additional context in comments.

Comments

2

I believe this is what you're looking for:

const char * const * string_a_ptr = static_cast<const char * const *>(a);

[Live example]

You could even drop the first const if you want (and it makes sense).

Explanation:

const void * a means that a points to something (void) which is const. Therefore, if you cast a to another pointer, it must also point to something that is const. In your case, you're casting it to a pointer to char*. That char* must therefore be const. The syntax for creating a constant pointer (not a pointer to a constant) is to put the const to the right of the *. Hence, char* const *.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.