指针转换的有效性 [英] Validity of pointer conversions

查看:88
本文介绍了指针转换的有效性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码是否保证始终有效?

1.


#include< iostream>

inline void some_func(int * p,const std :: size_t SIZE)

{

使用命名空间std;


for(size_t i = 0; i< SIZE; ++ i)

cout<< P [1] - ;< " ;

}

int main()

{

int array [10] [5] = {0};


some_func(array [0],sizeof(array)/ sizeof(** array));


std: :COUT<< std :: endl;

}

以上打印50个零。我认为它可以保证工作,因为所有

数组都是它们元素的序列。


2.


#include< iostream>

int main()

{

使用命名空间std;


int array [50] = {0};


int(* p)[5] = reinterpret_cast< int(*)[5](& array [0]) ;


for(size_t i = 0; i< 10; ++ i)

for(size_t j = 0; j< 5; ++ j )

cout<< P [i] [j]<<" " ;;


cout<<这是一个二维矩阵,即10x5矩阵。我认为

它保证与第一个原因相同,即

我们可以将整数的数组(序列)视为各种类型的整数

数组。

解决方案

1月5日上午10点02分,Ioannis Vranos< j ... @ no。 spamwrote:


以下代码是否保证始终有效?


1.


#include< iostream>


inline void some_func(int * p,const std :: size_t SIZE)

{

using namespace std;


for(size_t i = 0; i< SIZE; ++ i)

cout<< P [1] - ;< " ;


}


int main()

{

int array [10] [5] = {0};


some_func(array [0],sizeof(array)/ sizeof(** array));


std :: cout<< std :: endl;


}


以上打印50个零。我认为它可以保证工作,因为所有

数组都是它们元素的序列。



//你确定吗?试试......

int array [10] [5] = {99};


//并且就数组的函数而言:

模板< typename T,

const std :: size_t Rows,

const std :: size_t列>

void some_func(T(& arr) )[行] [列])

{

//做东西

}


//这个有效guarenteed

std :: vector<的std ::矢量< int vvn(10,std :: vector< int>(5,99));


>

2.


#include< iostream>


int main()

{

using namespace std;


int array [50] = {0};


int(* p)[5] = reinterpret_cast< int(* )[5](& array [0]);


for(size_t i = 0; i< 10; ++ i)

for( size_t j = 0; j <5; ++ j)

cout<< P [i] [j]<<" " ;;


cout<<结束;


}


这里p表现为二维矩阵,即10x5矩阵。我认为

它保证与第一个原因相同,即

我们可以将整数的数组(序列)视为各种类型的整数

数组。



任何用C ++编写的需要reinterpret_cast的东西都会在这里发出

警报。你只能猜测结果可能是什么(和

可能测试/用typeid检查结果)。

黑客不是编程。不惜一切代价尊重您的类型。它的

指令#1,没有例外。

无论何时你愚弄编译器都会阻止它帮助你编码。

基本上,你'将代码视为10x5矩阵,然后有一天

某些东西会改变你无法控制的东西。

你将在6个月后回来,看看在您的代码中,需要

修改它(即:添加功能)并覆盖Asprin平板电脑(想象

您的代码的客户端用户试图找到所有出)。一个苹果就像一个苹果,如果你像橙子一样威胁它,那么你最终会在一个叫做未定义行为的洞中堕落
。你会,这是一个问题

时间。

客户/客户不喜欢黑客,有时候 - 客户/

客户......是你。


1月5日下午4:02,Ioannis Vranos< j ... @ no.spamwrote:


以下代码是否保证始终有效?


1.


#include< iostream>


inline void some_func(int * p,const std :: size_t SIZE)

{

使用命名空间std;

for(size_t i = 0; i< SIZE; ++ i)

cout<< P [1] - ;< " " ;;

}


int main()

{

int array [10] [5] = {0};


some_func(array [0],sizeof(array)/ sizeof(** array));

std: :COUT<< std :: endl;

}


以上打印50个零。我认为它可以保证工作,因为所有数组都是它们元素的序列,所以



和?我没有看到你刚才所说的与b $ b和任何工作保证之间的任何关系。你有一个数组界限

违规,这是未定义的行为。并且已经有了检测它的b $ b(可能仍然是)实现,并且

将其视为错误条件。


2.


#include< iostream>


int main()

{

using namespace std;


int array [50] = {0};


int(* p)[5] = reinterpret_cast< int(*)[5](& array [0]);


for(size_t i = 0; i< 10; ++ i)

for(size_t j = 0; j< 5; ++ j)

cout<< P [i] [j]<<" " ;;

cout<< endl;

}


这里的p表现为二维矩阵,即10x5

矩阵。



几乎没有任何涉及reinterpret_cast的东西都可以使用。

关于标准保证的唯一一件事就是如果你

将值转换回原来的类型,并且你没有违反中间类型中任何对齐限制的


该值将等于原始值(因此,

指定由原始指针指定的相同对象)。


从实施质量的角度来看:标准
处理器的寻址架构的人来说,预计转换预计会不足为奇

,所以我希望这适用于大多数

实现。


我认为它保证可以出于同样的原因工作

作为第一个,



这与第一个完全无关。 reinterpret_cast与其他转换完全相同



我们可以将整数的数组(序列)视为

各种类型的整数数组。



如果你的意思是你可以玩尺寸游戏,只要元素总数不变,就可以获得
是b $ b只是假的。


-

James Kanze(GABI软件)电子邮件:ja ******* **@gmail.com

Conseils eninformatiqueorientéeobjet/

Beratung in objektorientierter Datenverarbeitung

9placeSémard,78210 St.-Cyr- l''école,法国,+ 33(0)1 30 23 00 34


1月5日下午6:35,Salt_Peter< pj_h。 .. @ yahoo.comwrote:


1月5日上午10点02分,Ioannis Vranos< j ... @ no.spamwrote:
< blockquote class =post_quotes>
以下代码是否保证始终有效?


1.


#include< iostream>


inline void some_func(int * p,const std :: size_t SIZE)

{

使用命名空间std;

for(size_t i = 0; i< SIZE; ++ i)

cout<< P [1] - ;< " " ;;

}


int main()

{

int array [10] [5] = {0};


some_func(array [0],sizeof(array)/ sizeof(** array) );

std :: cout<< std :: endl;

}


以上打印50零。我认为它可以保证工作,因为所有数组都是它们元素的序列,所以


//你确定吗?试试......

int array [10] [5] = {99};



这有什么变化?你有不同的初始值

(array [0] [0] == 99,所有其他元素== 0)。但是函数中还有一个数组边界违规,这是

未定义的行为。


/ /以及数组的函数:

template< typename T,

const std :: size_t Rows,

const std :: size_t列>

void some_func(T(& arr) )[行] [列])

{

//做东西

}


//这个有效。 guarenteed

std :: vector<的std ::矢量< int vvn(10,std :: vector< int>(5,99));



这样做有所不同。它使用99初始化所有

元素,而不是第一个用99,以及所有

其他用0.


2.

#include< iostream>


int main()

{

using namespace std;


int array [50] = {0};

int(* p)[5] = reinterpret_cast< int(*)[5](& array [0]);

for(size_t i = 0; i< 10; ++ i)

for(size_t j = 0; j <5; ++ j)

cout<< P [i] [j]<<" " ;;

cout<< endl;

}


这里的p表现为2-维矩阵,即10x5

矩阵。我认为它保证以同样的原因工作

作为第一个,也就是说我们可以将一个数组(序列)整数作为各种类型的整数数组来处理。


用C ++编写的任何需要reinterpret_cast的东西

在这里发出警报。你只能猜测结果

可能是什么(并且可能用typeid测试/检查结果)。



这不太正确 - 你可以用

reinterpret_cast做一些已定义行为的事情。但这不是其中之一。另一方面,标准中表达的

reinterpret_cast的意图是支持类型惩罚,在底层架构上合理到底是合理的,所以从

质量的实现观点,我希望它能在大多数架构上工作。


黑客不是节目。不惜一切代价尊重你的类型。

它的指令#1,没有例外。



由于某种原因,C ++有reinterpret_cast。我在使用malloc或垃圾收集等东西时使用它,例如,
。在

这样的情况下,它是必要的邪恶。


除了如此低的水平(取决于架构)

编程当然,这是一个有保障的问题,如果只是为了b / b
的可读性原因。

(其余的,我非常赞同这个部分我已经削减了。

任何涉及reinterpret_cast的东西都是黑客攻击,并且hack应该为绝对必要的情况保留
。)


-

James Kanze(GABI软件)电子邮件:ja ********* @ gmail.com

Conseils eninformatiqueorientée objet /

Beratung in objektorientierter Datenverarbeitung

9placeSémard,78210 St.-Cyr-l''coco,France,+ 33(0)1 30 23 00 34


Are the following codes guaranteed to work always?
1.

#include <iostream>
inline void some_func(int *p, const std::size_t SIZE)
{
using namespace std;

for(size_t i=0; i<SIZE; ++i)
cout<< p[i]<< " ";
}
int main()
{
int array[10][5]= {0};

some_func(array[0], sizeof(array)/sizeof(**array));

std::cout<< std::endl;
}
The above prints 50 zeros. I think it is guaranteed to work, since all
arrays are sequences of their elements.

2.

#include <iostream>
int main()
{
using namespace std;

int array[50]= {0};

int (*p)[5]= reinterpret_cast<int (*)[5](&array[0]);

for (size_t i= 0; i< 10; ++i)
for(size_t j=0; j<5; ++j)
cout<< p[i][j]<<" ";

cout<< endl;

}
Here p behaves as a 2-dimensional matrix, that is a 10x5 matrix. I think
it is guaranteed to work for the same reason as the first one, that is
we can treat an array (sequence) of integers as various types of integer
arrays.

解决方案

On Jan 5, 10:02 am, Ioannis Vranos <j...@no.spamwrote:

Are the following codes guaranteed to work always?

1.

#include <iostream>

inline void some_func(int *p, const std::size_t SIZE)
{
using namespace std;

for(size_t i=0; i<SIZE; ++i)
cout<< p[i]<< " ";

}

int main()
{
int array[10][5]= {0};

some_func(array[0], sizeof(array)/sizeof(**array));

std::cout<< std::endl;

}

The above prints 50 zeros. I think it is guaranteed to work, since all
arrays are sequences of their elements.

// Are you sure? try...
int array[10][5]= {99};

// and as far as a function for an array:
template< typename T,
const std::size_t Rows,
const std::size_t Columns >
void some_func(T(& arr)[Rows][Columns])
{
// do stuff
}

// this works. guarenteed
std::vector< std::vector< int vvn(10, std::vector<int>(5, 99));

>
2.

#include <iostream>

int main()
{
using namespace std;

int array[50]= {0};

int (*p)[5]= reinterpret_cast<int (*)[5](&array[0]);

for (size_t i= 0; i< 10; ++i)
for(size_t j=0; j<5; ++j)
cout<< p[i][j]<<" ";

cout<< endl;

}

Here p behaves as a 2-dimensional matrix, that is a 10x5 matrix. I think
it is guaranteed to work for the same reason as the first one, that is
we can treat an array (sequence) of integers as various types of integer
arrays.

Anything written in C++ that requires a reinterpret_cast sounds an
alarm here. You can only guess at what the result might be (and
possible test/check the result with typeid).
Hacking is not programming. Respect your types at all costs. Its
directive #1, no exceptions.
Anytime you fool a compiler you are preventing it to help you code.
Basicly, you''ll code as if it is a 10x5 matrix and then one day
something will change thats beyond your control.
You''ll come back 6 months from now, look at your code, needing to
modify it (ie: add features) and reach for the Asprin tablets (imagine
the client-user of your code trying to figure it all out). An apple is
an apple, if you threat it like an orange then you''ll eventually fall
in a hole called undefined behaviour. You will, its a question of
time.
Clients/Customers don''t like hacks, and sometimes - that client/
customer ... is you.


On Jan 5, 4:02 pm, Ioannis Vranos <j...@no.spamwrote:

Are the following codes guaranteed to work always?

1.

#include <iostream>

inline void some_func(int *p, const std::size_t SIZE)
{
using namespace std;
for(size_t i=0; i<SIZE; ++i)
cout<< p[i]<< " ";
}

int main()
{
int array[10][5]= {0};

some_func(array[0], sizeof(array)/sizeof(**array));
std::cout<< std::endl;
}

The above prints 50 zeros. I think it is guaranteed to work,
since all arrays are sequences of their elements.

And? I don''t see any relationship between what you just said
and any guarantee of working. You have an array bounds
violation, which is undeefined behavior. And there have been
(and maybe still are) implementations which detect it, and
treat it as an error condition.

2.

#include <iostream>

int main()
{
using namespace std;

int array[50]= {0};

int (*p)[5]= reinterpret_cast<int (*)[5](&array[0]);

for (size_t i= 0; i< 10; ++i)
for(size_t j=0; j<5; ++j)
cout<< p[i][j]<<" ";
cout<< endl;
}

Here p behaves as a 2-dimensional matrix, that is a 10x5
matrix.

Almost nothing involving reinterpret_cast is guaranteed to work.
About the only thing that the standard guarantees is that if you
cast the value back to its original type, and you haven''t
violated any alignment restrictions in the intermediate types,
the value will compare equal to the original value (and thus,
designate the same object designated by the original pointer).

From a quality of implementation point of view: the standard
does say that the conversion is expected to be "unsurprising"
for someone familiar with the addressing architecture of the
processor, so I would expect this to work on most
implementations.

I think it is guaranteed to work for the same reason
as the first one,

It is totally unrelated to the first. reinterpret_cast is quite
different from other conversions.

that is we can treat an array (sequence) of integers as
various types of integer arrays.

If by that you mean that you can play games with the dimensions,
as long as the total number of elements is unchanged, that is
simply false.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l''école, France, +33 (0)1 30 23 00 34


On Jan 5, 6:35 pm, Salt_Peter <pj_h...@yahoo.comwrote:

On Jan 5, 10:02 am, Ioannis Vranos <j...@no.spamwrote:

Are the following codes guaranteed to work always?

1.

#include <iostream>

inline void some_func(int *p, const std::size_t SIZE)
{
using namespace std;
for(size_t i=0; i<SIZE; ++i)
cout<< p[i]<< " ";
}

int main()
{
int array[10][5]= {0};

some_func(array[0], sizeof(array)/sizeof(**array));
std::cout<< std::endl;
}

The above prints 50 zeros. I think it is guaranteed to work,
since all arrays are sequences of their elements.

// Are you sure? try...
int array[10][5]= {99};

What does that change? You have different initial values
(array[0][0] == 99, all other elements == 0). But there is
still an array bounds violation in the function, which is
undefined behavior.

// and as far as a function for an array:
template< typename T,
const std::size_t Rows,
const std::size_t Columns >
void some_func(T(& arr)[Rows][Columns])
{
// do stuff
}

// this works. guarenteed
std::vector< std::vector< int vvn(10, std::vector<int>(5, 99));

That does something different. It initializes all of the
elements with 99, rather than the first with 99, and all of the
others with 0.

2.
#include <iostream>

int main()
{
using namespace std;

int array[50]= {0};
int (*p)[5]= reinterpret_cast<int (*)[5](&array[0]);
for (size_t i= 0; i< 10; ++i)
for(size_t j=0; j<5; ++j)
cout<< p[i][j]<<" ";
cout<< endl;
}

Here p behaves as a 2-dimensional matrix, that is a 10x5
matrix. I think it is guaranteed to work for the same reason
as the first one, that is we can treat an array (sequence)
of integers as various types of integer arrays.

Anything written in C++ that requires a reinterpret_cast
sounds an alarm here. You can only guess at what the result
might be (and possible test/check the result with typeid).

That''s not quite true---there are a few things you can do with
reinterpret_cast which have defined behavior. But this isn''t
one of them. On the other hand, the expressed intent of
reinterpret_cast in the standard is to support type punning, in
so far as reasonable on the underlying architecture, so from a
quality of implementation point of view, I would expect it to
work on most architectures.

Hacking is not programming. Respect your types at all costs.
Its directive #1, no exceptions.

C++ has reinterpret_cast for a reason. I use it, for example,
when implementing things like malloc or garbage collection. In
such cases, it''s a necessary evil.

In anything but such low level (architecture dependent)
programming, of course, it''s a guaranteed problem, if only for
reasons of readability.

(For the rest, I very much agree with the part I''ve cut.
Anything involving reinterpret_cast is a hack, and hacks should
be reserved for the cases where they are absolutely necessary.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l''école, France, +33 (0)1 30 23 00 34


这篇关于指针转换的有效性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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