 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Michal Kowalski Guest
|
Posted: Mon Dec 08, 2003 10:58 am Post subject: a[i] not equivalent to *(a+i)? |
|
|
Hello,
I have a question regarding old good array and pointers. I remember reading
a
remark by Bjarne Stroustrup that a[i] is not equivalent to *(a+i) when it
comes
to reaching pass the end of an array. Say I have an array int a[100]. Then
(a+100)
is safe, but &a[100] is not. Master didn't explain what he meant by those
two being
not equivalent. I can kind of feel &a[100] is not quite right, but what does
C++
standard say? Where does similarity end? Am I overlooking something obvious?
Can someone comment on this issue please.
Thank you,
MK
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Mon Dec 08, 2003 9:29 pm Post subject: Re: a[i] not equivalent to *(a+i)? |
|
|
In article <M2XAb.67706$zY1.30782 (AT) newssvr25 (DOT) news.prodigy.com>, Michal
Kowalski <michal_kowalski (AT) hotmail (DOT) com> writes
| Quote: | Hello,
I have a question regarding old good array and pointers. I remember reading
a
remark by Bjarne Stroustrup that a[i] is not equivalent to *(a+i) when it
comes
to reaching pass the end of an array. Say I have an array int a[100]. Then
(a+100)
is safe, but &a[100] is not. Master didn't explain what he meant by those
two being
not equivalent. I can kind of feel &a[100] is not quite right, but what does
C++
standard say? Where does similarity end? Am I overlooking something obvious?
Can someone comment on this issue please.
|
I think this is strictly language law stuff. In theory &a[100] is
equivalent to &*(a+100) which has the singular pointer (a+100)
dereferenced before its address is taken. When dealing with raw C-style
arrays I suspect this is purely of academic interest but were you to be
dealing with a user defined subscript operator then it would be a very
different issue.
--
Francis Glassborow ACCU
If you are not using up-to-date virus protection you should not be reading
this. Viruses do not just hurt the infected but the whole community.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Maciej Sobczak Guest
|
Posted: Mon Dec 08, 2003 9:36 pm Post subject: Re: a[i] not equivalent to *(a+i)? |
|
|
Hi,
Michal Kowalski wrote:
| Quote: | to reaching pass the end of an array. Say I have an array int a[100]. Then
(a+100)
is safe, but &a[100] is not.
|
The problem comes from the fact that Standard differentiates between a
"valid pointer value" and "dereferenceable pointer".
The first is a pointer which has legal value in the sense that you can
compare such pointer to another. Or you can do pointer arithmetic on
such values - one example of such pointer arithmetic is:
int a[100];
int *p = (a + 100); // ok
The second kind (dereferenceable) means that you can read the value that
it points to. The difference is that the Standard requires the
"one-past-the-end" pointer to be valid for all arrays, but does not
require it to be dereferenceable. In other words, you can point to
(a+100), but you cannot read it:
int i = *p; // illegal!
p -= 50;
int i = *p; // but here ok, because p is dereferenceable
The difference between (a+100) and &a[100] is that the first is only a
pointer arithmetic which gives the "one-past-the-end", legal pointer
value, whereas the second tries to get the address of *object*, which
does not exist - in other words, a[100] is "executed" before & and
a[100] is not a legal l-value, because it is (by definition) the same as
*(a + 100) and (a + 100) is not dereferenceable.
--
Maciej Sobczak : http://www.msobczak.com/
Programming : http://www.msobczak.com/prog/
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Mon Dec 08, 2003 10:42 pm Post subject: Re: a[i] not equivalent to *(a+i)? |
|
|
"Michal Kowalski" <michal_kowalski (AT) hotmail (DOT) com> wrote
| Quote: | I have a question regarding old good array and pointers. I remember
reading a remark by Bjarne Stroustrup that a[i] is not equivalent to
*(a+i) when it comes to reaching pass the end of an array. Say I have
an array int a[100]. Then (a+100) is safe, but &a[100] is not. Master
didn't explain what he meant by those two being not equivalent. I can
kind of feel &a[100] is not quite right, but what does C++ standard
say? Where does similarity end? Am I overlooking something obvious?
Can someone comment on this issue please.
|
I think that Stroustrup must have been anticipating a change which
didn't take place. For built-in arrays, both in C++ and in C90, the
expression is undefined behavior; in C99, there is a special rule which
allows it ONLY as the operand of a unary & operator. For containers in
the STL, it is also undefined behavior, and wht at least some
implementations, it actually fails.
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Michal Kowalski Guest
|
Posted: Tue Dec 09, 2003 10:53 am Post subject: Re: a[i] not equivalent to *(a+i)? |
|
|
Thank you all,
Your answers are very helpful. Just to give credit where it's due: I believe
master was
well aware of uncertain status of (a+100) construction James mentioned.
MK
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Maciej Sobczak Guest
|
Posted: Tue Dec 09, 2003 11:03 am Post subject: Re: a[i] not equivalent to *(a+i)? |
|
|
Hi,
Francis Glassborow wrote:
| Quote: | In theory &a[100] is
equivalent to &*(a+100) which has the singular pointer (a+100)
|
Assuming that 24.1/5 applies to pointer to arrays:
"Dereferenceable and past-the-end values are always nonsingular."
Which brings us to the question what does it really mean that the
pointer (or iterator) is "singular". This word is used in the Standard
but not explained beside few words stating that iterator with singular
values "are not associated with any container".
I think that one-past-the-end is associated with the container.
Is there any formal (or better clear ) definition what singular
really means?
| Quote: | When dealing with raw C-style
arrays I suspect this is purely of academic interest
|
Because the compiler can eliminate & and * standing one beside the other
(this is exactly what we do mentally), but even outside the academy I
can imagine implementations where such violations are trapped.
--
Maciej Sobczak : http://www.msobczak.com/
Programming : http://www.msobczak.com/prog/
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Tue Dec 09, 2003 5:06 pm Post subject: Re: a[i] not equivalent to *(a+i)? |
|
|
In article <hobBb.68066$hE3.57444 (AT) newssvr25 (DOT) news.prodigy.com>, Michal
Kowalski <michal_kowalski (AT) hotmail (DOT) com> writes
| Quote: | Your answers are very helpful. Just to give credit where it's due: I believe
master was
well aware of uncertain status of (a+100) construction James mentioned.
|
I do not think that there is any uncertainty wrt to (a+100) the
uncertainty is with &a[100]. Given:
T a[100];
Both a[100] and *(a+100) give undefined behaviour. In practice I think
most compilers will convert &a[100] to the well-defined a+100 but they
are not required to do so. C99 IIRC explicitly requires that &* be
treated as an identity operator but C++ does not.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Tue Dec 09, 2003 8:04 pm Post subject: Re: a[i] not equivalent to *(a+i)? |
|
|
Maciej Sobczak <no.spam (AT) no (DOT) smap.com> wrote
| Quote: | Francis Glassborow wrote:
In theory &a[100] is
equivalent to &*(a+100) which has the singular pointer (a+100)
Assuming that 24.1/5 applies to pointer to arrays:
"Dereferenceable and past-the-end values are always nonsingular."
Which brings us to the question what does it really mean that the
pointer (or iterator) is "singular". This word is used in the Standard
but not explained beside few words stating that iterator with singular
values "are not associated with any container".
I think that one-past-the-end is associated with the container.
Is there any formal (or better clear ) definition what singular
really means?
When dealing with raw C-style
arrays I suspect this is purely of academic interest
Because the compiler can eliminate & and * standing one beside the
other (this is exactly what we do mentally), but even outside the
academy I can imagine implementations where such violations are
trapped.
|
You don't even need imagination. Centerline once sold such an
implementation.
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dietmar Kuehl Guest
|
Posted: Tue Dec 09, 2003 10:03 pm Post subject: Re: a[i] not equivalent to *(a+i)? |
|
|
"Michal Kowalski" <michal_kowalski (AT) hotmail (DOT) com> wrote:
| Quote: | Your answers are very helpful. Just to give credit where it's due: I believe
master was
well aware of uncertain status of (a+100) construction James mentioned.
|
Well for 'int a[100]', the expression '(a+100)' is perfectly valid and
yields a non-dereferencable past the end iterator. The resulting pointer
can only be used in certain expressions. It can, however, not be
dereferenced.
The expression '&a[100]' yields undefined behavior, because the
sub-expression 'a[100]' would access a non-existing element. To answer
the question from your subject for built-in arrays 'a[n]':
- 'a[i]' is equivalent to '*(a + i)' (and this is also equivalent to
'*(i + a)' which in turn is equivalent to 'i[a]'; but this is a
completely irrelevant sidetrack...): both yield a reference to an
element for '0 <= i && i < n' and are invalid otherwise.
- '&a[i]' is equivalent to '(a + i)' if 'i != n'. In
case 'i == n', the expression '(a+i)' is valid, while '&a[i]' is not.
If 'i < 0 || n <= i', both expressions are invalid while for
'0 <= i && i < n' both expressions are valid.
Often, the case 'a + n' is important: it is used to obtain a "past the
end"-iterator for an array object.
--
Phaidros eaSE - Easy Software Engineering: <http://www.phaidros.com/>
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Bjarne Stroustrup Guest
|
Posted: Wed Dec 10, 2003 11:28 am Post subject: Re: a[i] not equivalent to *(a+i)? |
|
|
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote in message news:<d6652001.0312080748.40b60eac (AT) posting (DOT) google.com>...
| Quote: | "Michal Kowalski" <michal_kowalski (AT) hotmail (DOT) com> wrote in message
news:<M2XAb.67706$zY1.30782 (AT) newssvr25 (DOT) news.prodigy.com>...
I have a question regarding old good array and pointers. I remember
reading a remark by Bjarne Stroustrup that a[i] is not equivalent to
*(a+i) when it comes to reaching pass the end of an array. Say I have
an array int a[100]. Then (a+100) is safe, but &a[100] is not. Master
didn't explain what he meant by those two being not equivalent. I can
kind of feel &a[100] is not quite right, but what does C++ standard
say? Where does similarity end? Am I overlooking something obvious?
Can someone comment on this issue please.
I think that Stroustrup must have been anticipating a change which
didn't take place. For built-in arrays, both in C++ and in C90, the
expression is undefined behavior; in C99, there is a special rule which
allows it ONLY as the operand of a unary & operator. For containers in
the STL, it is also undefined behavior, and wht at least some
implementations, it actually fails.
|
I think this is a case where one must be very careful attributions. On
my "issues" page http://www.research.att.com/~bs/3rd_issues.html I
say:
______
pg 42 I use
char vc2[200];
copy(&vc1[0],&vc1[200],&vc2[200]);
The issue is whether taking the address of one-past-the-last element
of an array is conforming C and C++. I could make the example clearly
conforming by a simple rewrite:
copy(vc1,vc1+200,vc2+200);
However, I don't want to introduce addition to pointers at this point
of the book. It is a surprise to most experienced C and C++
programmers that &vc2[200] isn't completely equivalent to vc2+200. In
fact, it was a surprise to the C committee also and I expect it to be
fixed in the upcoming revision of the standard. (resolved for C9x - bs
10/13/9 . (this means that the example was ok in K&R C, in ARM C++,
an error in C89 and ISO C++, and ok in C9x - a thorny issue).
_____
I suspect that "a thorny issue" is a good characterization, and that
anything less than a longish explanation will add to the confusion.
- Bjarne Stroustrup; http://www.research.att.com/~bs
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
John Potter Guest
|
Posted: Wed Dec 10, 2003 11:30 am Post subject: Re: a[i] not equivalent to *(a+i)? |
|
|
On 9 Dec 2003 06:03:54 -0500, Maciej Sobczak <no.spam (AT) no (DOT) smap.com>
wrote:
| Quote: | Francis Glassborow wrote:
In theory &a[100] is
equivalent to &*(a+100) which has the singular pointer (a+100)
Assuming that 24.1/5 applies to pointer to arrays:
"Dereferenceable and past-the-end values are always nonsingular."
|
It does not. A, IMO misguided DR, has changed that to allow singular
past-the-end values.
| Quote: | Which brings us to the question what does it really mean that the
pointer (or iterator) is "singular". This word is used in the Standard
but not explained beside few words stating that iterator with singular
values "are not associated with any container".
|
The original intent used uninitialized pointers as an example of
singular. It was stated that no operation other than assignment
is permitted. The DR now states that past-the-end iterators may be
singular which means that they can not be read for any reason including
comparison. All this because they wanted to allow a null pointer to be
an off the end iterator for a singly linked list. Because singular was
never well defined, the common use of null as a singular == unique value
was used when it was intended to mean an unusable value like a
singularity of a function.
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Matthias Hofmann Guest
|
Posted: Wed Dec 10, 2003 8:24 pm Post subject: Re: a[i] not equivalent to *(a+i)? |
|
|
John Potter <jpotter (AT) falcon (DOT) lhup.edu> schrieb in im Newsbeitrag:
[email]lapctvck2p3rmvtsq7arqcsndc7b29kt06 (AT) 4ax (DOT) com[/email]...
| Quote: | On 9 Dec 2003 06:03:54 -0500, Maciej Sobczak
wrote:
Francis Glassborow wrote:
In theory &a[100] is
equivalent to &*(a+100) which has the singular pointer (a+100)
Assuming that 24.1/5 applies to pointer to arrays:
"Dereferenceable and past-the-end values are always nonsingular."
It does not. A, IMO misguided DR, has changed that to allow singular
past-the-end values.
Which brings us to the question what does it really mean that the
pointer (or iterator) is "singular". This word is used in the Standard
but not explained beside few words stating that iterator with singular
values "are not associated with any container".
The original intent used uninitialized pointers as an example of
singular. It was stated that no operation other than assignment
is permitted. The DR now states that past-the-end iterators may be
singular which means that they can not be read for any reason including
comparison. All this because they wanted to allow a null pointer to be
an off the end iterator for a singly linked list. Because singular was
never well defined, the common use of null as a singular == unique value
was used when it was intended to mean an unusable value like a
singularity of a function.
|
So when is a past-the-end value singular and when is it not? What about the
ubiquitous
for ( it = list.begin(); it != list.end(); ++it );
If no comparison with past-the-end values are allowed, is this illegal code
in future versions of the standard?
Matthias
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Wed Dec 10, 2003 8:32 pm Post subject: Re: a[i] not equivalent to *(a+i)? |
|
|
[email]bs (AT) research (DOT) att.com[/email] (Bjarne Stroustrup) wrote in message
news:<188b3370.0312091746.3e22a207 (AT) posting (DOT) google.com>...
| Quote: | kanze (AT) gabi-soft (DOT) fr wrote in message
news:<d6652001.0312080748.40b60eac (AT) posting (DOT) google.com>...
"Michal Kowalski" <michal_kowalski (AT) hotmail (DOT) com> wrote in message
news:<M2XAb.67706$zY1.30782 (AT) newssvr25 (DOT) news.prodigy.com>...
I have a question regarding old good array and pointers. I
remember reading a remark by Bjarne Stroustrup that a[i] is not
equivalent to *(a+i) when it comes to reaching pass the end of an
array. Say I have an array int a[100]. Then (a+100) is safe, but
&a[100] is not. Master didn't explain what he meant by those two
being not equivalent. I can kind of feel &a[100] is not quite
right, but what does C++ standard say? Where does similarity end?
Am I overlooking something obvious? Can someone comment on this
issue please.
I think that Stroustrup must have been anticipating a change which
didn't take place. For built-in arrays, both in C++ and in C90, the
expression is undefined behavior; in C99, there is a special rule
which allows it ONLY as the operand of a unary & operator. For
containers in the STL, it is also undefined behavior, and wht at
least some implementations, it actually fails.
I think this is a case where one must be very careful attributions.
|
Or simply more careful reading of the orginal posting. I just missed a
not. With regards to the technical issues:
| Quote: | I suspect that "a thorny issue" is a good characterization, and that
anything less than a longish explanation will add to the confusion.
|
I'd say that this more or less sums it up. The simple statement is that
&a[nbElem] is undefined behavior in C++. Regardless of whether a is a
built in array or an STL container. Anything beyond that enters into
the realm of implementation techniques and C compatibility, with
probably a good deal of personal opinions regarding style thrown in as
well.
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
John Potter Guest
|
Posted: Wed Dec 10, 2003 8:33 pm Post subject: Re: a[i] not equivalent to *(a+i)? |
|
|
On 10 Dec 2003 06:28:42 -0500, [email]bs (AT) research (DOT) att.com[/email] (Bjarne Stroustrup)
wrote:
Issues-errata:
To make the issue clear, pg 42 has the correct &vc2[0] and does not
copy off the end of vc2. The issue with &vc1[200] will be clearer
without the added error.
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Old Wolf Guest
|
Posted: Thu Dec 11, 2003 11:42 am Post subject: Re: a[i] not equivalent to *(a+i)? |
|
|
| Quote: | The expression '&a[100]' yields undefined behavior, because the
sub-expression 'a[100]' would access a non-existing element. To answer
the question from your subject for built-in arrays 'a[n]':
- 'a[i]' is equivalent to '*(a + i)' (and this is also equivalent to
'*(i + a)' which in turn is equivalent to 'i[a]'; but this is a
completely irrelevant sidetrack...): both yield a reference to an
element for '0 <= i && i < n' and are invalid otherwise.
- '&a[i]' is equivalent to '(a + i)' if 'i != n'. In
case 'i == n', the expression '(a+i)' is valid, while '&a[i]' is not.
If 'i < 0 || n <= i', both expressions are invalid while for
'0 <= i && i < n' both expressions are valid.
Often, the case 'a + n' is important: it is used to obtain a "past the
end"-iterator for an array object.
|
Does any of this apply to:
extern char a[100];
extern char a[]; /* does that make &a[0] invalid? */
extern char *a;
or even
#include
int put101(char *a)
{
char *p = a + 101;
/* char *p = &a[101]; -- better? worse? identical? */
while (*a && a < p) putchar(*a++);
putchar('n');
}
int main()
{
char a[100] = "Hello, world!";
put101(a);
}
People (in C anyway) add and subtract pointers all the time.
It would horrify me to learn that this program is
undefined behaviour. Until now I have used the &a[i] syntax
instead of (a+i) in situations like this (I find it more readable).
Is this a bad habit?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|