这是C ++ code便携式? (假设多维数组有连续的内存布局) [英] Is this C++ code portable? (assuming multidimensional arrays have continuous memory layout)

查看:145
本文介绍了这是C ++ code便携式? (假设多维数组有连续的内存布局)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,对不起,我的英语,如果我做任何语法错误,等等...

我的问题是,当我们有一个二维数组,那么如果我是正确的,从计算机和C / C ++的角度来看,这只是一个很长的一维数组,该指数刚刚帮助编译器映射到具体地址。

这code段工程在Visual C ++,但是我想知道,这code是否便携符合 应用于标准(C ++ 98),不会造成对其他架构和/或操作系统的惊喜:

  INT ARR [] [3] = {1,5,3,7,5,2,7,8,9};
const int的ARR_NUM = sizeof的(ARR)/的sizeof(int);在为int * PTR = reinter pret_cast< INT *>(ARR); // NOT:INT(*)[] [3]!
的for(int i = 0; I< ARR_NUM ++我){
    COUT<< ptr的[1] - ;&下; ENDL;
}


解决方案

Standardese

多维数组的元素存储在连续行优先顺序,因此人工索引是可移植的:

C ++ 98 8.3.4 / 1:


  

数组类型的对象包含一个连续分配的非空
  设置T型的N个子对象。


显然,对于多维数组适用递归。

然而,这种使用 reinter pret_cast 是不可移植的。标准说(C ++ 98,5.2.10 / 1)


  

...]否则,结果是一个rvalue和[...],
  阵列到指针,[...]标准转换所执行
  前pression诉


在换句话说,传递改编立即触发所述阵列的衰变的指针其第一个元素。然后,(C ++ 98,5.2.10 / 3)来了包罗万象的


  

reinter pret_cast 执行的映射是实现定义的。


一节的其余部分列出了一些例外的,指定始终明确定义类型转换。看到作为他们没有适用于这里,得出的结论是,从技术上讲,实现定义默认。

最后结论

从理论上讲,这是不可移植。实际上,只要架构是相同的(如86)我当然希望中投能可靠地工作。

幸运的是,你不必承担这样的因为作为任何别人 <一个href=\"http://stackoverflow.com/questions/10618473/is-this-c-$c$c-portable-assuming-multidimensional-arrays-have-continuous-mem/10618866#comment13760969_10618473\">have上述,像为int * PTR = ARR [0] 做同样的事情,并保证便携性。

First of all, sorry for my english if i make any grammar mistakes, etc ...

My question is, that when we have a two dimensional array, then if i am right, from the point of the computer and C/C++, it's just a long one dimensional array, the indices are just helping the compiler to map to the concrete address.

This code fragment works in Visual C++, however I would like to know, whether this code is portable and conforms to the standard (C++98), not causing surprises on other architectures and/or operating systems:

int arr[][3] = { 1, 5, 3, 7, 5, 2, 7, 8, 9 };
const int ARR_NUM = sizeof(arr) / sizeof(int);

int* ptr = reinterpret_cast<int*>(arr);    // NOT: int(*)[][3] !!!
for (int i = 0; i < ARR_NUM; ++i) {
    cout << ptr[i] << endl;
}

解决方案

Standardese

The elements of the multidimensional array are stored sequentially in row-major order, so the manual indexing is portable:

C++98, 8.3.4/1:

An object of array type contains a contiguously allocated non-empty set of N sub-objects of type T.

Obviously for a multidimensional array this applies recursively.

However, this use of reinterpret_cast is not portable. The standard says (C++98, 5.2.10/1) that

[...] otherwise, the result is an rvalue and the [...], array-to-pointer, [...] standard conversions are performed on the expression v.

In other words, passing arr immediately triggers a decay of the array to a pointer to its first element. Then (C++98, 5.2.10/3) comes the catch-all

The mapping performed by reinterpret_cast is implementation-defined.

The rest of the section lists a number of exceptions to this, specifying casts that are always well-defined. Seeing as none of them applies here, the conclusion is that technically it's implementation-defined by default.

Final conclusion

Theoretically speaking, this is not portable. Practically, as long as the architectures are the same (e.g. x86) I would certainly expect the cast to work reliably.

Fortunately you don't have to assume anything like that because as others have mentioned, something like int* ptr = arr[0] does the same thing and is guaranteed portable.

这篇关于这是C ++ code便携式? (假设多维数组有连续的内存布局)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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