Is it legal to cast a pointer to array reference using static_cast in C++?

送分小仙女□ 提交于 2019-11-27 06:37:54

问题


I have a pointer T * pValues that I would like to view as a T (&values)[N]

In this SO answer https://stackoverflow.com/a/2634994/239916, the proposed way of doing this is

T (&values)[N] = *static_cast<T(*)[N]>(static_cast<void*>(pValues));

The concern I have about this is. In his example, pValues is initialized in the following way

T theValues[N];
T * pValues = theValues;

My question is whether the cast construct is legal if pValues comes from any of the following constructs:

1:

T theValues[N + M]; // M > 0
T * pValues = theValues;

2:

T * pValues = new T[N + M]; // M >= 0

回答1:


Short answer: You are right. The cast is safe only if pValues is of type T[N] and both of the cases you mention (different size, dynamically allocated array) will most likely lead to undefined behavior.


The nice thing about static_cast is that some additional checks are made in compile time so if it seems that you are doing something wrong, compiler will complain about it (compared to ugly C-style cast that allows you to do almost anything), e.g.:

struct A { int i; };
struct C { double d; };

int main() {
    A a;
    // C* c = (C*) &a; // possible to compile, but leads to undefined behavior
    C* c = static_cast<C*>(&a);
}

will give you: invalid static_cast from type ‘A*’ to type ‘C*’

In this case you cast to void*, which from the view of checks that can be made in compile time is legal for almost anything, and vice versa: void* can be cast back to almost anything as well, which makes the usage of static_cast completely useless at first place since these checks become useless.

For the previous example:

C* c = static_cast<C*>(static_cast<void*>(&a));

is no better than:

C* c = (C*) &a;

and will most likely lead to incorrect usage of this pointer and undefined behavior with it.


In other words:

A arr[N];
A (&ref)[N] = *static_cast<A(*)[N]>(&arr);

is safe and just fine. But once you start abusing static_cast<void*> there are no guarantees at all about what will actually happen because even stuff like:

C *pC = new C;
A (&ref2)[N] = *static_cast<A(*)[N]>(static_cast<void*>(&pC));

becomes possible.



来源:https://stackoverflow.com/questions/21317140/is-it-legal-to-cast-a-pointer-to-array-reference-using-static-cast-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!