Address of an array = address of its 1st element: undecidable question?

B

Ben Bacarisse

James Kuyper said:
Chris said:
Chris Torek wrote:
[The C Standard] *does* seem to say that:
(void *)&t == (void *)&t[0]
will always produce 1.

I would like to emphasise your answer in this way :

"It does *seem* to say that:"

So, if i understand well, the Standard doesn't make certain the
above equality yields 1 ?

I think that it *does* say that. The wording is not as clear as
I would like, though. If others disagree with me (about the result
of the comparison above always being 1), I would like to see their
reasoning, and perhaps a DR is called for.

When you convert a pointer from a pointer type to void*, where does
the resulting pointer point? I know where I and everyone else expects
it to point; I know where it will point under essentially every
implementation of C. I don't know where the standard actually says
so. There is such a statement for char*, but not for void*.

Hmm... I would argue that (void *)&obj must still be a pointer to the
object 'obj' so the wording of 6.3.2.3p7 applies to this pointer as
well. In other words (char *)(void *)&obj must point to the "first"
byte of obj. Since char * and void * must have the same
representation (the footnote suggesting interchangeability even in
unions) then (void *)&obj can't really be anything other a pointer to
the start of obj.

I would rather see a stronger statement to the effect that all
sequences of defined pointer conversions of a pointer value that end
with a value of type T * produce the same T * value[1]. I think would
not impact any real implementations but would ensure what most people
expect to be true. For example, given

T array[N];

we would know that (void *)&array == (void *)array and also that array
== (T *)&array. This is only one step further than the existing
wording that a converted pointer must convert back to the original
type. It extends it to converting back even after being further
converted (which might in fact be the simplest wording).

Of course if the existing wording (guaranteeing that a converted
pointer converts back to one that compares equal) is already intended
to apply even if the pointer is further converted then we are already
there.

[1] Strictly: that all such pointers compare equal.
 
J

James Kuyper

Ben Bacarisse wrote:
....
Hmm... I would argue that (void *)&obj must still be a pointer to the
object 'obj' ...

That's a fine thing to argue; do you have a supporting citation from the
standard? We all "know" that it is true, but as far as I can see the
standard does not explicitly say so.
 
L

lawrence.jones

There's been lots of discussion about the following quote from me:
| I'm not aware of any definition (or even description) of the C language
| that said that taking the address of an array was equivalent to taking
| the address of the first member of the array.

This quote has been taken out of context and seriously misinterpreted.
It was part of a discussion of ancient (pre-ANSI) C compilers that
simply ignored & when applied to an array. Such compilers interpreted
&a as a, which is in turn interpreted as &a[0] in value contexts. The
above quote was my saying that I know of no justification whatsoever for
that behavior. It has nothing to do with ANSI/ISO C.

-- Larry Jones

I'm getting disillusioned with these New Years. -- Calvin
 
B

Ben Bacarisse

James Kuyper said:
Ben Bacarisse wrote:
...

That's a fine thing to argue; do you have a supporting citation from
the standard?

No. Please, if the argument is not enough for you (and I agree it is
shaky) then file a DR. memcpy is miss-used all over the place if the
conversion to void * is not defined how we expect it to be. At least
one example of memcmp in the standard is wrong without this argument.
We all "know" that it is true, but as far as I can see
the standard does not explicitly say so.

And I, too, would be happier if it did. However, I think one is
permitted, at times, to say "what else could it be?". I agree that it
*could* be pointer to the object pointing somewhere other than the
beginning (which is why the rest of my argument is required) but to
assume that a permitted pointer conversion might make a pointer that
does not point to the same object (not place, just object) is taking
literalism further than I would.
 
J

jameskuyper

Ben said:
No. Please, if the argument is not enough for you (and I agree it is
shaky) then file a DR.

The last time I checked, it seemed to me that to file a DR you had to
be a member of the C committee (or, more precisely, a member of one of
the national bodies who are the members of the C committee). i haven't
sufficient free time to spare for committee membership
responsibilities. I've raised this issue before on comp.std.c, with
several members of the committee listening in, but I didn't inspire
enough interest to get one of them to file a DR.

That's not quite true: the committee member most interested was one
who routinely reads into the text of the standard promises that aren't
actually present, saying that the intent was clear, and that only
someone with malicious intent could possibly interpret the words of
the standard in a way inconsistent with the "obvious" intent. He calls
this "common sense"; I call it "reading the minds of the committee
members"; either way, whether it's common sense or mind-reading
abilities; it's something I clearly lack. His interest in the issue
was strong, but only in the negative sense, so he's not likely to file
such a DR.
 
J

jameskuyper

CBFalconer said:
The result is not dereferencable, so it doesn't have to point
anywhere (although it probably does). It just has to hold enough
information to allow it to be converted back to the original type
on demand.

There's two problems with that interpretation. First of all, the
results of == and != on void* operands is defined in terms of what
those pointer values point at. Taking the standard's lack of
definition literally, this implies that void* values can never be
usefully compared.

The second problem has to do with the fact that the standard requires
that void* have the same representation as a pointer to a character
type. That is, the same bit pattern indicates the same location in
memory, regardless of whether it's the bit pattern of a void* or a
pointer to a character type. The standard fails to identify where the
result points when a pointer to one type is converted to a pointer to
a different type. If that were intentional, it would render the "same
representation" requirement meaningless, or at least useless.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top