Hi all,

My first post here -- I've been trying to update some old code that uses C-style casts into the C++ equivalent, and I've stumbled on one cast that I can't figure out how to convert.

This isn't the code that was giving me issues, but it reproduces the problem:

Old code would look like this:

short g_myshort;

const short& someFunction()
{
  return g_myshort;
}

int main()
{
  g_myint = 5;
  int* pnum = (int*)(&someFunction());
}

I'd like to replace that last call with something like:

int* pnum = static_cast<int*>(&someFunction());

or possibly

const int* pnum = static_cast<const int*>(&someFunction());

but in both cases, the compiler yells: cannot convert from 'const short *__w64' to int */const int*.

I've tried nesting a const_cast inside the static_cast, and vice versa, but neither has worked. Any ideas? Or am I forced to stick to the C style cast here.

And yes, I realize I could store the return value and get it done that way, but I'm interested from a theory angle on why the C-style cast can get it done in one line and the C++-style seemingly can't.

Thanks!

Dani AI

Generated

Short answer: the compiler is preventing an unsafe pointer reinterpretation. static_cast only performs certain well‑defined conversions (numeric conversions, related class pointers, pointer↔void conversions, etc.). It will not convert a const short * to an int * because those pointer types are unrelated. A C‑style cast appears to “work” because it tries multiple C++ casts (including const_cast and reinterpret_cast) until one succeeds — which hides the danger.

A compact roadmap of the right choices:

  • For value conversion (take the numeric value in the short and use it as an int), copy the value into an int and use that address. This is safe and portable:
int tmp = static_cast<int>(someFunction()); // make an int from the returned short
int* p = &tmp;
  • For treating the underlying bytes as a different type (bitwise reinterpretation), do not cast a pointer and dereference it. That usually violates the strict‑aliasing rule and can be undefined behavior. Prefer std::bit_cast (C++20) when the sizes match, or std::memcpy to copy the representation safely:
short s = someFunction();
int i;
std::memcpy(&i, &s, sizeof(s)); // safe byte copy; semantics depend on sizes/endianness
  • For class pointers use static_cast for upcasts, dynamic_cast for checked downcasts, and avoid reinterpret_cast except for low‑level code where portability and aliasing are already handled.

was right to call reinterpret_cast a last resort; it will perform the pointer reinterpretation that static_cast refuses, but it does not make the resulting dereference safe. ’s curiosity about the “why” is spot on: C++ forces the programmer to choose exactly which potentially unsafe operation is intended (remove constness, reinterpret bits, or do a checked polymorphic cast) rather than hiding it behind a single C‑style cast.

Recommended Answers

All 6 Replies

short* pnum = static_cast<short*>(&const_cast<short&>(someFunction())); or this const short* pnum = static_cast<const short*>(&someFunction());

short* pnum = static_cast<short*>(&const_cast<short&>(someFunction())); or this const short* pnum = static_cast<const short*>(&someFunction());

Well, this leaves the variable as a short. Testing further, it looks like the simplest reduction of the problem is the casting of pointers:

short myShort = 0;
int iTest = static_cast< int >( myShort );

works, but

short* pmyShort = &myShort;
int* piTest = static_cast< int* >( pmyShort )

does not. I guess I don't understand why?

And what's wrong with leaving it as a short pointer? Casting it as an int pointer will not give it any more precision.

And what's wrong with leaving it as a short pointer? Casting it as an int pointer will not give it any more precision.

I was hoping to concentrate more on the problem than the specifics used in the example. The actual pointers involved are all user classes in an inheritance hierarchy -- short and int were just used for convenience.

maybe you need a better example that describes more accurately what you are trying to do. Maybe something like this???

class base
{
 // blabla
};

class derived : public base
{
  // blabla
};

void foo( base* pBase)
{
   derived* pDerived = reinterpret_cast<derived*>(pBase);
}

Thanks for sticking with it. Anyhow, I think what you're recommending -- reinterpret_cast -- will work, however, I've always been told its like a last resort. From MSDN: "The result of a reinterpret_cast cannot safely be used for anything other than being cast back to its original type. Other uses are, at best, nonportable." I actually am, in this case, converting a child class back to its parent class so that a function can use it as an argument. Since the parent pointer supports all the operations the child does, I guess I'm just confused why I can't static cast that.

maybe you need a better example that describes more accurately what you are trying to do. Maybe something like this???

class base
{
 // blabla
};

class derived : public base
{
  // blabla
};

void foo( base* pBase)
{
   derived* pDerived = reinterpret_cast<derived*>(pBase);
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.