Can an array have a delayed padding?

It is understood that arrays in C cannot insert padding between their elements . However, is there a rule saying that they cannot add a final complement at the end of the array as a whole?

i.e. Is this program guaranteed to give the same results everywhere?

#include <stdio.h> int main(void) { typedef char a[3]; typedef ab[3]; printf("%zu %zu\n", sizeof(a), sizeof(b)); // -> 3 9 } 

As far as I can tell, adding an end byte or five to size a might not violate the array access rules in an attempt to erroneously optimize ( b[1][1] still exactly matches *(&b + sizeof(a) * 1 + 1) regardless of the size of the objects a contained in it, and access beyond the length of the contained a is UB in any case).

I cannot find anywhere else in the C standard where it actually says directly that the size of the array is the size of the element type times the number of elements. 6.5.3.4 only says that sizeof returns the "number of bytes" in the array (it gives sizeof array / sizeof array[0] as an example code, but it's just an example - it doesn't say that it should work, and it doesn't work give any details).

An implicit guarantee is useful for writing portable code that depends on exact data layouts, for example. transfer of packed RGB values:

 typedef uint8_t RGB[3]; RGB * data = ...; glColorPointer(3, GL_UNSIGNED_BYTE, 0, data); 

(OK, so OpenGL can take step values, so this is a bad example, but you get the point)

In this regard, I assume from the widespread notion (even for an example in the standard) that you can get the number of elements in an array with sizeof , that this is likely to be true everywhere, anyway, there are any known situations where this is not the case ?

+5
source share
1 answer

I believe that it was never considered necessary for the standard to actually indicate that arrays do not have a complement, for the simple reason that there is absolutely no reason why such a complement can ever be useful for any implementation.

However, I believe that the standard prohibits such padding through the description of the == operator.

6.5.9 Equality Operators

Semantics

6 Two pointers compare the same, if and only if [...] or one is a pointer to one end of the end of one array object, and the other to a pointer to the beginning of another array object that occurs immediately after the first array object in the address space.

Considering

 int array[2][2]; 

the expression &array[0][2] indicates that the pointer is one after the end of the first subobject of the array. &array[1][0] is a pointer to the second subobject of the array, which immediately follows the first array in memory. These pointers should compare equals. If int[2] has a final complement, if sizeof(int[2]) > 2 * sizeof(int) , I can’t imagine how any implementation could make two pointers comparable as equal.

+6
source

Source: https://habr.com/ru/post/1207539/


All Articles