Tho*_*ing 16 c++ arrays casting static-cast type-safety
我有一个T * pValues我想要查看的指针T (&values)[N]
在这个SO答案/sf/answers/184449611/中,建议的方法是
T (&values)[N] = *static_cast<T(*)[N]>(static_cast<void*>(pValues));
Run Code Online (Sandbox Code Playgroud)
我对此的担忧是.在他的例子中,pValues以下面的方式初始化
T theValues[N];
T * pValues = theValues;
Run Code Online (Sandbox Code Playgroud)
我的问题是,如果pValues来自以下任何构造,则构造构造是否合法:
T theValues[N + M]; // M > 0
T * pValues = theValues;
Run Code Online (Sandbox Code Playgroud)
T * pValues = new T[N + M]; // M >= 0
Run Code Online (Sandbox Code Playgroud)
简短的回答:你是对的.只有在pValues类型T[N]的情况下,强制转换是安全的,并且您提到的两种情况(不同大小,动态分配的数组)很可能导致未定义的行为.
关于这种做法的好处static_cast是,一些额外的检查在编译时作出所以如果它似乎你正在做的事情错了,编译器会抱怨它(相比于丑陋的C样式转换,允许你做几乎任何事情),例如:
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);
}
Run Code Online (Sandbox Code Playgroud)
会给你: invalid static_cast from type ‘A*’ to type ‘C*’
在这种情况下,您可以转换为void*,从编译时可以进行的检查视图几乎适用于任何事情,反之亦然:void*几乎可以将其转换回任何东西,这使得static_cast在第一时间使用完全无用因为这些检查变得无用.
对于前面的示例:
C* c = static_cast<C*>(static_cast<void*>(&a));
Run Code Online (Sandbox Code Playgroud)
并不比:
C* c = (C*) &a;
Run Code Online (Sandbox Code Playgroud)
并且很可能会导致错误地使用此指针和未定义的行为.
换一种说法:
A arr[N];
A (&ref)[N] = *static_cast<A(*)[N]>(&arr);
Run Code Online (Sandbox Code Playgroud)
很安全,很好.但是一旦你开始滥用,static_cast<void*>就完全没有任何关于实际发生的事情的保证,因为即使是这样的东西:
C *pC = new C;
A (&ref2)[N] = *static_cast<A(*)[N]>(static_cast<void*>(&pC));
Run Code Online (Sandbox Code Playgroud)
成为可能.
| 归档时间: |
|
| 查看次数: |
2682 次 |
| 最近记录: |