Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  • Line 1, Error C2734 (C++): const object must be initialized if not extern

  • Line 2, Error C3892 (C++): you cannot assign to a variable that is const

  • Line 2, Error C2166 (C): l-value specifies const object

The reason behind these compilation errors:

  • const ptr_t ptr is interpreted as void* const ptr instead of const void* ptr

  • With void* const ptr, you cannot change the pointer but you can change the pointed data

  • With const void* ptr, you can change the pointer but you cannot change the pointed data


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

like image 568
barak manos Avatar asked Mar 17 '26 18:03

barak manos


2 Answers

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>>>>;
like image 71
Kerrek SB Avatar answered Mar 19 '26 06:03

Kerrek SB


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.

like image 37
Lundin Avatar answered Mar 19 '26 06:03

Lundin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!