它是合法的投在C ++中使用的static_cast一个指向数组引用? [英] Is it legal to cast a pointer to array reference using static_cast in C++?

查看:134
本文介绍了它是合法的投在C ++中使用的static_cast一个指向数组引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个指针 T * pValues​​ ,我想以查​​看一个 T(安培;数值)[N]

在此SO回答 http://stackoverflow.com/a/2634994/239916 ,这样做的方式提出这是

  T(安培;数值)[N] = *的static_cast< T(*)[N]>(的static_cast<无效*>(pValues​​));

我对这个令人担忧的是。在他的例子, pValues​​ 按以下方式进行初始化

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

我的问题是投结构是否合法,如果 pValues​​ 来自以下任何构造:

1

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

2

  T * pValues​​ =新的T [N + M]。 // M> = 0


解决方案

简短的回答:你说得对。演员是安全的前提 pValues​​ 的类型为 T [N] 以及两者的你提到的情况下(不同尺寸,动态分配的数组)将最有可能导致的未定义行为


关于的static_cast 的好处是,一些额外的检查在编译时作出的,所以如果你似乎正在做的事情不对,编译器会抱怨它(相比,丑陋的C样式转换,可以让你做几乎任何事情),例如:

 结构A {INT I; };
结构C {1双D; };诠释主(){
    A中;
    // C * C =(C *)及一个; //可以通过编译,但会导致不确定的行为
    C * C =的static_cast c为C * GT;(安培; A);
}

会给你:无效的static_cast从类型A *键入C *

在这种情况下,转换到无效* ,从检查的角度,可以在编译时作出是合法的,几乎所有的东西,反之亦然:无效* 可转换回几乎所有的东西为好,这让的static_cast 完全无用的,因为这些检查首位变得毫无用处。

对于previous例如:

  C * C =的static_cast c为C * GT;(的static_cast<无效*>(安培; A));

没有比好:

  C * C =(C *)及一个;

和将最有可能导致该指针的不正确使用和未定义行为它。


在换句话说:

  A ARR [N];
A(&安培; REF)[N] = *的static_cast< A(*)[N]>(安培; ARR);

是安全的,就好了。但是,一旦你开始滥用的static_cast<无效*> 没有保证在所有关于什么会实际发生,因为即使东西,如:

  C * PC =新的C;
A(&安培; REF2)[N] = *的static_cast< A(*)[N]>(的static_cast<无效*>(安培; PC));

变得可能。

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

In this SO answer http://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

解决方案

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.

这篇关于它是合法的投在C ++中使用的static_cast一个指向数组引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆