Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Pointer Equality for Different Array Objects

Reply
Thread Tools

Pointer Equality for Different Array Objects

 
 
Shao Miller
Guest
Posts: n/a
 
      02-04-2012
On 2/3/2012 02:11, Kaz Kylheku wrote:
> On 2012-02-03, Shao Miller<(E-Mail Removed)> wrote:
>> But for any stricter run-time bounds-checking, such as catching
>> 'a[i][j]' where the ranges for 'i' and 'j' aren't known at
>> translation-time and go out-of-bounds, there could be checks for each
>> dimension of a multi-dimensional array, but is that consistent with C?

>
> You know, who cares? All that matters is: is this check valuable to the user?
> Checks can be stronger or weaker than the standard language. Suppose that the
> C standard explicitly said that an array is just flat memory that can be
> aliased with any multi-dimensional array geometry. Well, someone might still
> want some of their code to pass array dimension bounds checks.
>


Absolutely it can be valuable. But if I write a program which I expect
to be strictly conforming and either translating it or running it
behaves differently for different implementations, that's upsetting.

>> It would seem unfair to give the array subscripting notation 'a[0][3]'
>> some kind of bounds-preferential treatment versus the identical '*(*(a +
>> 0) + 3)' notation.

>
> No, but the preferential treatment could actually stem from the
> "a + displacement" where a is not a pointer, but an array (that converts to a
> pointer on evaluation) and not from the choice of notation.
>


If that works, would you encourage and support a proposal to incorporate
that into Standard C? Maybe it's pretty reasonable to add something to
pointer arithmetic along the lines of "if the pointer was the immediate
result of the evaluation of an lvalue having an array type, then the
number of elements of the array object is the number of elements in that
array type."

> In such an expression, there is enough info to know that the displacement is in
> bounds with respect to the static type of a, regardless of the larger
> container in which that array finds itself.
>


And if we wish to "forget" about the bounds of array, would it be
reasonable for us to simply do:

int a[2][2] = { { 0 } };
int x;
x = ((int *) a[0])[3];

? Or maybe 'x = (1 ? a[0] : 0)[3];'? That seems easy.

>> But we do see references to "provenance" in at least one defect report,
>> and this seems related to the "provenance" of a pointer. If it "came
>> from" an array with certain boundaries, then pointer arithmetic is only
>> defined for its use with those boundaries, despite the fact that another
>> pointer with difference boundaries is identical in every other way.
>>
>> Of course "provenance" seems like a "gray area," since you can combine
>> things (such as via bit-wise operators). Then whence did they come?

>
> Clearly, at some point provenance has to be severed. A good rule of thumb (if
> provenance were to stop being a gray area) might be that a pointer value
> that is derived from a conversion from array, plus any combination of
> displacements, has provenance from that array. As soon as&..*.. is involved,
> it should be lost: e.g.&a[0] or&*(a + 0) ought to drop provenance.


Oh, ok. So when the evaluation of 'a' would yield a pointer value, the
bounds of the array object would be defined by the type of 'a', then you
could apply '*' and designate the object, then apply '&' and point to
that object without the previous bounds. Interesting! I guess that'd
require some changes to the text of '&' and '*'. Would you encourage
and support a proposal to incorporate that into Standard C?

I appreciate your discussion. While you're here, could you clarify
if the following suggest undefined behaviour?

#1:

int a[2][2] { { 0 } };
int * p = a[0] + 0;
int * q = a[1] + 1;
ptrdiff_t diff = q - p;

#2:

union u_test {
int a[2][2];
int b[4];
};
union u_test test = { { { 0 } } };

int * p = test.a[1] + 1;
int * q = test.b + 3;
ptrdiff_t diff = q - p;

q = test.b + 0;
diff = q - p;

--
"The stationery store has moved. Aaargh!"
 
Reply With Quote
 
 
 
 
Shao Miller
Guest
Posts: n/a
 
      02-06-2012
On 2/2/2012 19:34, Shao Miller wrote:
> (More bounds-checking.)
>
> Wait a minute... N1256 6.5.9p6:
>
> "Two pointers compare equal if and only if both are null pointers, both
> are pointers to the same object (including a pointer to an object and a
> subobject at its beginning) or function, both are pointers to one past
> the last element of the same array object, or one is a pointer to one
> past the end of one array object and the other is a pointer to the start
> of a different array object that happens to immediately follow the first
> array object in the address space.94)"
>
> So if we have:
>
> union u_test {
> int a[2][2];
> int b[4];
> };
> union u_test test = { { { 0 } } };
> int x = &test.a[1][1] == &test.b[3];
>
> Is 'x' zero or one?
>
> If we can claim, for the purposes of supporting bounds-checking, that
> '&test.a[1][1]' points into an 'int[2]' and nothing more, and that
> '&test.b[3]' points into an 'int[4]' and nothing more, then aren't these
> pointers pointing to distinct objects?
>
> If they're pointing to the same object, why might they not be for the
> purposes of 6.5.6p8?
>
> Just to illustrate an identical [declaration]:
>
> int x = (*(test.a + 1) + 1) == (test.b + 3);
>
>


Maybe using a 'typedef' makes it look different?

typedef int array_of_two_ints[2];
union u_test {
array_of_two_ints a[2];
int b[4];
};
union u_test test = { { { 0 } } };
int x;
array_of_two_ints * ptr_into_array_of_two_ints;
int * ptr_into_int;

/*
* Point into the second element of 'a', so the
* element type is 'array_of_two_ints'
*/
ptr_into_array_of_two_ints = &test.a[1];


/*
* Point into the second element of the array object
* with type 'array_of_two_ints', so the element
* type is 'int'
*/
ptr_into_int = &ptr_into_array_of_two_ints[1];

/*
* 'ptr_into_int' does _not_ point to:
* - A subobject at the beginning of the 'test.b'
* array object
* - The array object 'test.b'
* - A function
* - No object (it's non-null)
* - One past the array object 'test.b'
* - An array object that happens to immediately
* follow 'test.b' in the address space
* - An object that is not an element of an array
* object
* '&test.b[3] points to:
* - The fourth element of the 'test.b' array
* object
*/
x = ptr_into_int == &test.b[3];
x = ptr_into_int - &test.b[3];

Perhaps similarly:

struct s_common {
double d;
int i[2];
};
struct s_foo {
struct s_common common;
short s;
};
struct s_bar {
struct s_common common;
long l;
};
union u_foobar {
struct s_foo foo;
struct s_bar bar;
};
union u_foobar test;
int * p;
int * q;
int x;

p = &test.foo.common.i[1];
q = &test.bar.common.i[1];

/*
* 'p' does _not_ point to:
* - A subobject at the beginning of the
* 'test.bar.common.i' array object
* - The array object 'test.bar.common.i'
* - A function
* - No object (it's non-null)
* - One past the array object 'test.bar.common.i'
* - An array object that happens to immediately
* follow 'test.bar.common.i' in the
* address space
* - An object that is not an element of an array
* object
* 'q' points to:
* - The second element of the 'test.bar.common.i'
* array object
*/
x = p == q;
x = p - q;

Fortunately, of course, they point to the same byte in the same
contiguous region of data storage.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
pointer to an array vs pointer to pointer subramanian100in@yahoo.com, India C Programming 5 09-23-2011 10:28 AM
Comparing objects for equality Jens Thoms Toerring Perl Misc 0 05-07-2007 11:25 PM
Equality of hashref objects bill Perl Misc 7 02-05-2005 07:54 PM
pointer equality and inheritance, take 2 sb C++ 2 04-03-2004 02:34 PM
pointer equality and inheritance sb C++ 4 04-03-2004 02:28 PM



Advertisments