Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two- and one-dimensional arrays equivalence in C++

It is known that two- and one-dimensional arrays can be used equivalently, by simple coordinate conversion. Is such equivalence guaranteed by the C++ standard, or maybe it's the most convenient way of organizing data, but doesn't have to be obeyed everywhere? For example, is the following code compiler-independent?

std::ofstream ofbStream;
ofbStream.open("File", std::ios::binary);
char Data[3][5];

for(int i=0; i<3; ++i)
for(int j=0; j<5; ++j)
{
    Data[i][j] = (char) 5*i+j;
}

ofbStream.write(&Data[0][0], 15);

ofbStream.close();

The program is expected to write the numbers: 0, 1, 2, ..., 14 to a file.

like image 572
Adayah Avatar asked Jan 13 '23 07:01

Adayah


1 Answers

In practice, this is just fine. Any compiler that doesn't do that would have countless problems with existing code.

Very strictly speaking, though, the pointer arithmetic needed is Undefined Behavior.

char Data[3][5];
char* p = &Data[0][0];
p + 7; // UB!

5.7/5 (emphasis mine):

When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that that difference of the subscripts of the resulting and original array elements equals the integral expression. ... If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

The Standard does guarantee that all the array elements are adjacent in memory and are in a specific order, and that dereferencing a pointer with the correct address (no matter how you got it) refers to the object at that address, but it doesn't guarantee that p + 7 does anything predictable, since p and p + 7 don't point at elements of the same array or past-the-end. (Instead they point at elements of elements of the same array.)

like image 106
aschepler Avatar answered Jan 21 '23 10:01

aschepler