Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this static_cast not allowed?

I have an object of class A that I want to allocate on a custom stack object. To do this, I simply move the stack pointer as many bytes as the object is in size and return its previous value:

class A : public B {}; //B is from a precompiled library

class stack {
public:
    stack(void): _top(&_storage[0]) {}

    template <typename T>
    inline T* push(void) {
        T* ptr = static_cast<T*>(_top);

        _top += sizeof(T);

        return ptr;
    }

    //...

private:
    char _storage[1024];
    char* _top;
};

stack _stack;

int main(int argc, char** argv) {
    A* a = _stack.push<A>(); //ignore the lack of a constructor call

    return 0;
}

Visual C++ simply tells me that static_cast cannot convert from char* to A*. A regular C style cast does not give me this error, but I'd rather be more explicit and avoid a dynamic cast (A inherits from another class, but does not contribute to the vtable it doesn't have). Is there any difference between the two in this case?

like image 325
NmdMystery Avatar asked Jan 15 '14 05:01

NmdMystery


People also ask

What happens when you perform a static_cast?

Static Cast: This is the simplest type of cast which can be used. It is a compile time cast.It does things like implicit conversions between types (such as int to float, or pointer to void*), and it can also call explicit conversion functions (or implicit ones).

Should I use static_cast?

You shouldn't use static_cast for casting down an inheritance hierarchy, but rather dynamic_cast . That will return either the null pointer or a valid pointer.

What happens when static_cast fails?

As we learnt in the generic types example, static_cast<> will fail if you try to cast an object to another unrelated class, while reinterpret_cast<> will always succeed by "cheating" the compiler to believe that the object is really that unrelated class.

Why is static_cast better than C style cast?

In short: static_cast<>() gives you a compile time checking ability, C-Style cast doesn't. static_cast<>() is more readable and can be spotted easily anywhere inside a C++ source code, C_Style cast is'nt. Intentions are conveyed much better using C++ casts.


1 Answers

As others have said, the solution is to use reinterpret_cast, which is meant to be used when casting between unrelated pointer types:

T* ptr = reinterpret_cast<T*>(_top);

If you use placement new instead, you not only avoid the casting problem but you also fix the problem of not calling the constructor for types that have a constructor:

T* ptr = new(_top) T();
like image 187
Remy Lebeau Avatar answered Oct 23 '22 11:10

Remy Lebeau