Re: multi dimensional arrays as one dimension array
- From: James Kuyper <jameskuyper@xxxxxxxxxxx>
- Date: Fri, 29 Aug 2008 11:08:00 GMT
vippstar@xxxxxxxxx wrote:
On Aug 29, 6:39 am, pete <pfil...@xxxxxxxxxxxxxx> wrote:vipps...@xxxxxxxxx wrote:The subject might be misleading.Stepping through a one dimensional array
Regardless, is this code valid:
#include <stdio.h>
void f(double *p, size_t size) { while(size--) printf("%f\n", *p++); }
int main(void) {
double array[2][1] = { { 3.14 }, { 42.6 } };
f((double *)array, sizeof array / sizeof **array);
return 0;
}
Assuming casting double [2][1] to double * is implementation defined
or undefined behavior, replace the cast with (void *).
Since arrays are not allowed to have padding bytes in between of
elements, it seems valid to me.
and on through a consecutive one dimensional array
is only defined for elements of character type
and only because
any object can be treated as an array of character type.
So as I understand it you are saying my code invokes undefined
behavior.
In which hypothetical (or real, if such implementation does exist)
implementation my code won't work, and why?
The key point is the pointer conversion. At the point where that conversion occurs, the compiler knows that (double*)array == array[0]. It's undefined if any number greater than 1 is added to that pointer value, and also if that pointer is dereferenced after adding 1 to it.
Because the behavior is undefined, it's possible for a conforming implementation to provide a run-time bounds check. This would require the use of some mechanism such as a "fat" pointer, which contains not only the information about where it points, but also information about the upper and lower limits on where it can point. The implementation can set the limits on the pointer value created by that conversion, based upon the limits for array[0].
Implementations with support for run-time bounds checking are rare; the performance cost is significant, it's almost always optional, and usually not the default option, so you're unlikely to run into this issue by accident.
The more tricky possibility is also something you're far more likely to run into. Because the behavior is undefined in those cases, a compiler is allowed to generate code which is optimized in a way that assumes that those cases don't actually come up; because it makes that assumption, such code can fail catastrophically if that assumption is violated.
This is most likely to occur as the result of anti-aliasing assumptions. The compiler is allowed to generate code which assumes that array[0][i] is never an alias for array[1][j], regardless of the values of i and j. As a result, it can drop anti-aliasing checks from code that would need such checks if that assumption could be violated without making the behavior undefined.
I don't see any way for that to come up in this particular example, but in more complicated cases it can come up. If 'p' and 'array' were both in scope at the same place somewhere in the code, the compiler would not be required to prevent the problems that might occur if p[j] and array[1][i] happened to refer to the same location in memory. It is required to cover the possibility that p[j] and array[0][i] refer to the same object, but only if 'i' and 'j' are both 0. It's also required to handle the possibility that p+j refers to the same location as array[0][i], but only if 'i' and 'j' are both in the range [0,1].
.
- References:
- multi dimensional arrays as one dimension array
- From: vippstar
- Re: multi dimensional arrays as one dimension array
- From: pete
- Re: multi dimensional arrays as one dimension array
- From: vippstar
- multi dimensional arrays as one dimension array
- Prev by Date: Re: C99 portability challenge
- Next by Date: Re: C99 portability challenge
- Previous by thread: Re: multi dimensional arrays as one dimension array
- Next by thread: Re: multi dimensional arrays as one dimension array
- Index(es):
Relevant Pages
|