使用C ++中的static_cast来转换数组引用的指针是否合法? [英] Is it legal to cast a pointer to array reference using static_cast in C++?

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

问题描述

我有一个 T(& values)[N] 的指针 T * pValues $ c>



在此SO回答中 http://stackoverflow.com/ a / 2634994/239916 ,建议的方式是

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

我关心的问题是。在他的示例中, pValues 以下列方式初始化

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

我的问题是,如果 pValues 来自以下任何结构:



1:



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



2:



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


解决方案

是对的。只有 pValues 的类型为 T [N] 和您提及的两种情况(不同大小,动态分配的数组)最有可能导致未定义的行为






static_cast 是在编译时进行一些额外的检查,所以如果看起来你做错了,编译器会抱怨它(与丑陋的C风格的转换你几乎可以做任何事情),例如:

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

int main(){
A a;
// C * c =(C *)& a; //可能编译,但导致未定义的行为
C * c = static_cast< C *>(& a);
}

会提供: invalid_cast from type'A *'键入'C *'



在这种情况下,您转换为 void * ,因为从编译时可以进行检查的角度看,几乎任何东西都是合法的,反之亦然: void * 也可以投射回几乎任何东西,这使得 static_cast 的使用在第一时间完全无用,因为这些检查变得无用。



对于上一个示例:

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

不比:

  C * c =(C *)& a; 

,很有可能导致此指针和 / em>


$ b $ b

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

安全无虞。但是一旦你开始滥用 static_cast< void *> ,实际上并没有什么保证,因为即使像下面这样的东西:

  C * pC = new C; 
A(& ref2)[N] = * static_cast< A(*)[N]>(static_cast< void *>(& 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天全站免登陆