spraff
spraff

Reputation: 33395

Why can I static_cast void* to int* but not to int*&?

An API uses void* to store untyped pointer offsets. It's a bit hacky, but okay whatever.

To express my offset arithmetic, I tried doing something like this

int main ()
{
    void * foo;

    foo = static_cast <int *> (nullptr) + 100;

    static_cast <int * &> (foo) += 100;
}

The last line fails to compile (gcc)

x.cpp:7:28: error: invalid static_cast from type ‘void*’ to type ‘int*&’

The fix is simple:

foo = static_cast <int *> (foo) + 100;

But why isn't the first one allowed?

Before you answer "because the standard says so", why does the standard say so? Is the first method somehow dangerous? Or is it just an oversight?

Upvotes: 2

Views: 523

Answers (1)

user743382
user743382

Reputation:

It's not allowed for the same reason that int i; static_cast<long &>(l) = 3L; isn't allowed.

Sure, on a lot of implementations (where int and long have the same size, representation and alignment), it could work. But the rules for which casts are valid are mostly the same for all implementations, and clearly this could never work on platforms where int and long have different sizes, meaning it'd be impossible to allow accessing one as the other on those platforms.

Historically, there have been implementations on which void * and int * have different representations.

Later, after the standard stating that accessing void * as if it were an int * is invalid, implementations also started optimising on the assumption that valid programs do not do that:

void *f (void **ppv, int **ppi) {
  void *result = *ppv;
  *ppi = nullptr;
  return result;
}

The implementation is allowed to optimise this to

void *f (void **ppv, int **ppi) {
  *ppi = nullptr;
  return *ppv;
}

and such optimisations, when they reduce code size or increase efficiency, are commonplace nowadays. If f were allowed to be called as void *pv = &pv; f (pv, &static_cast<int*&>(pv));, this optimisation would be invalid. Because such optimisations have proved useful, the rules are unlikely to change.

Upvotes: 3

Related Questions