在 C++ 中使用 static_cast 转换指向数组引用的指针是否合法? [英] Is it legal to cast a pointer to array reference using static_cast in C++?
问题描述
我有一个指针 T * pValues
,我想将其视为 T (&values)[N]
I have a pointer T * pValues
that I would like to view as a T (&values)[N]
在这个 SO 答案 https://stackoverflow.com/a/2634994/239916 中,建议的做法这是
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));
我对此的担忧是.在他的例子中,pValues
的初始化方式如下
The concern I have about this is. In his example, pValues
is initialized in the following way
T theValues[N];
T * pValues = theValues;
我的问题是,如果 pValues
来自以下任何构造,则转换构造是否合法:
My question is whether the cast construct is legal if pValues
comes from any of the following constructs:
T theValues[N + M]; // M > 0
T * pValues = theValues;
2:
T * pValues = new T[N + M]; // M >= 0
推荐答案
简短回答:您说得对.仅当 pValues
的类型为 T[N]
并且您提到的两种情况(不同大小,动态分配的数组)最有可能导致 未定义的行为.
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.
static_cast
的好处是在编译时进行了一些额外的检查,所以如果你似乎做错了什么,编译器会抱怨它(与丑陋的 C 风格强制转换相比,允许你做几乎任何事情),例如:
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);
}
会给你:invalid static_cast from type ‘A*’ to type ‘C*’
在这种情况下,您将强制转换为 void*
,从可以在编译时进行的检查的角度来看,它几乎对任何事情都是合法的,反之亦然:void*
也可以转换回几乎任何东西,这使得 static_cast
的使用一开始就完全无用,因为这些检查变得无用.
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.
对于前面的例子:
C* c = static_cast<C*>(static_cast<void*>(&a));
并不比:
C* c = (C*) &a;
并且很可能会导致此指针的错误使用和未定义的行为.
and will most likely lead to incorrect usage of this pointer and undefined behavior with it.
换句话说:
A arr[N];
A (&ref)[N] = *static_cast<A(*)[N]>(&arr);
是安全的,很好.但是一旦你开始滥用 static_cast
就不能保证实际会发生什么,因为即使是这样的东西:
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));
成为可能.
这篇关于在 C++ 中使用 static_cast 转换指向数组引用的指针是否合法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!