barak manos
barak manos

Reputation: 30136

How can I instantiate a const typedef pointer?

The following piece of code:

typedef void* ptr_t;

void func()
{
    const ptr_t ptr; // Line 1
    ptr = ...;       // Line 2
}

Yields the following compilation errors:

The reason behind these compilation errors:


My goal here is to prevent possible attempts to change the contents of the memory pointed by ptr.

I can work-around this problem using #define ptr_t void* instead of typedef void* ptr_t.

But it doesn't feel like a proper solution in terms of coding correctness. Is there any alternative?

Thanks

Upvotes: 2

Views: 820

Answers (3)

Kerrek SB
Kerrek SB

Reputation: 477338

Here's a C++ solution to turn a pointer-to-object into a pointer-to-const-object:

#include <type_traits>

template <typename T>
using more_const_ptr = typename std::enable_if<
    std::is_pointer<T>::value,
    typename std::add_pointer<
        typename std::add_const<
            typename std::remove_pointer<T>::type>::type>::type>::type;

Usage:

using p = int *;    // or "typedef int * p;" in C++03

int a = 10;
more_const_ptr<p> q = &a;
// *q = 20;  // Error, q is "const int *"

(In C++14 there are useful shortcuts that make this more readable:)

template <typename T>
using more_const_ptr = std::enable_if_t<
    std::is_pointer<T>::value,
    std::add_pointer_t<std::add_const_t<std::remove_pointer_t<T>>>>;

Upvotes: 4

Benjamin Lindley
Benjamin Lindley

Reputation: 103733

#include <type_traits>
...
typedef std::remove_pointer<ptr_t>::type base_type;
typedef base_type const* const_ptr_t;

If ptr_t is actually a template parameter, rather than a concrete type, then you will need to throw a typename in there:

typedef typename std::remove_pointer<ptr_t>::type base_type;

Upvotes: 3

Lundin
Lundin

Reputation: 214265

In line 1, as you say you have a pointer type and then make it const. This means you have a constant pointer to (non-constant) data. Declaring it as type const won't solve anything, because C specifies that such a declaration is equivalent to const type.

There is no work-around. Generally, it is a bad idea to hide a pointer underneath a typedef. This makes the code very hard to read, even if you have a coding standard for variable naming. Just look at the Windows API for a perfect example of how to turn the C language into something less readable.

So the quick & dirty solution is to keep digging your hole deeper by declaring a typedef const void* cptr_t;. Or indeed use a macro, it is an equally bad solution.

The good solution is to forget all about hiding pointers behind typedefs and other such attempts to change the well-known C or C++ language into some mysterious, personal macro language.

Upvotes: 3

Related Questions