5

I just can't find out how this simple example can be compiled in C++ :

class C
{
  public:
    static const void* noop = static_cast<const void*> (0x1);
};

Because of the static storage constraint I want, the only cast possible here would be static_cast but it is incompatible with this int-to-ptr cast.

error: invalid static_cast from type ‘int’ to type ‘const void*’

How can an integer value be statically casted to a pointer type?

5
  • 1
    You're getting a descriptive error with your static_cast, I bet. Can you share it? Commented Jun 24, 2014 at 23:14
  • how about this Commented Jun 24, 2014 at 23:20
  • 1
    This code doesn't work for me even if I try to assign NULL instead of 0x1. It gives error: non-const static data member must be initialized out of line (clang++) Commented Jun 24, 2014 at 23:20
  • 1
    Have you tried reinterpret_cast? Commented Jun 24, 2014 at 23:21
  • As I state in my answer it seems like using intptr_t leads to a better solution. Commented Jun 30, 2014 at 2:26

4 Answers 4

4

The problem here is that although you are declaring a const void* the const qualifier doesn't apply to the pointer but to the address that this pointer points to.

This means that noop is not a static const member variable and as all non const static member variables needs to be defined and initialized in a single translation unit outside class's definition like the example below:

class C {
  public:
    static const void *noop;
};

const void* C::noop = (const void*) 0x1;

Live Demo

The following solution:

class C {
public:
  static constexpr const void* noop = reinterpret_cast<const void*>(0x1);
};

Although, it compiles and works fine in GCC isn't valid C++ (e.g., it doesn't compile with either clang or VC++2013) because according to the standard § 5.19/2 Constant Expressions [expr.const] the result of a reinterpret_cast can't be a constant expression.

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

3 Comments

Also, why did you make the variable non-const?
@BenVoigt in the example provided by the OP is non-const.
@40two: Sorry, I spent too much time looking at the constexpr attempts.
4

reinterpret_cast is what you are looking for (raw interpretation of the bytes of an int to a const void* pointer)

Also, you need constexpr for in-class initialization of static data member :

class C
{
  public:
    static constexpr const void* noop = reinterpret_cast<const void*>(0x1);
};

static_cast doesn't work since there is no combination of user-defined or implicit conversions that would transform an int to a const void*.

EDIT:

This solution is not standard C++ (reinterpret_cast is not allowed in constant expressions), 40two solution's is correct.

4 Comments

@DrewDormann: Nope: coliru.stacked-crooked.com/a/685b3b1ee008f14c. It needs both.
I missed the constexpr ! C++11 gives me headache... Thank you !
@quantdev No, it's a pointer to a const void but the pointer is non-const.
This is wrong the result of reinterpret_cast is never a constant expression.
1

40two has fixed the compile error, but also made the member non-const, which is undesirable because it hinders optimization and opens to door to accidental mutation.

Best:

class C {
  public:
    static const void* const noop;
};

const void* const C::noop = reinterpret_cast<const void*>(0x1);

Comments

1

An alternate solution which also comes from the question 40two references: constexpr and initialization of a static const void pointer with reinterpret cast, which compiler is right?, is to use intptr_t which is:

integer type capable of holding a pointer

This also allows you to make the member variable a constexpr:

class C
{
  public:
    static constexpr intptr_t noop = 0x1 ;
};

then you can use reinterpret_cast at the point where it is used:

const void * vPtr = reinterpret_cast<void*>( C::noop ) ;

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.