C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

a[i] not equivalent to *(a+i)?
Goto page 1, 2, 3, 4, 5  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Michal Kowalski
Guest





PostPosted: Mon Dec 08, 2003 10:58 am    Post subject: a[i] not equivalent to *(a+i)? Reply with 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.

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





PostPosted: Mon Dec 08, 2003 9:29 pm    Post subject: Re: a[i] not equivalent to *(a+i)? Reply with quote



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





PostPosted: Mon Dec 08, 2003 9:36 pm    Post subject: Re: a[i] not equivalent to *(a+i)? Reply with quote



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





PostPosted: Mon Dec 08, 2003 10:42 pm    Post subject: Re: a[i] not equivalent to *(a+i)? Reply with quote

"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





PostPosted: Tue Dec 09, 2003 10:53 am    Post subject: Re: a[i] not equivalent to *(a+i)? Reply with quote

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





PostPosted: Tue Dec 09, 2003 11:03 am    Post subject: Re: a[i] not equivalent to *(a+i)? Reply with quote

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 Wink ) 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





PostPosted: Tue Dec 09, 2003 5:06 pm    Post subject: Re: a[i] not equivalent to *(a+i)? Reply with quote

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





PostPosted: Tue Dec 09, 2003 8:04 pm    Post subject: Re: a[i] not equivalent to *(a+i)? Reply with quote

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 Wink ) 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





PostPosted: Tue Dec 09, 2003 10:03 pm    Post subject: Re: a[i] not equivalent to *(a+i)? Reply with quote

"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





PostPosted: Wed Dec 10, 2003 11:28 am    Post subject: Re: a[i] not equivalent to *(a+i)? Reply with quote

[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/9Cool. (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





PostPosted: Wed Dec 10, 2003 11:30 am    Post subject: Re: a[i] not equivalent to *(a+i)? Reply with quote

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





PostPosted: Wed Dec 10, 2003 8:24 pm    Post subject: Re: a[i] not equivalent to *(a+i)? Reply with quote


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





PostPosted: Wed Dec 10, 2003 8:32 pm    Post subject: Re: a[i] not equivalent to *(a+i)? Reply with quote

[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





PostPosted: Wed Dec 10, 2003 8:33 pm    Post subject: Re: a[i] not equivalent to *(a+i)? Reply with quote

On 10 Dec 2003 06:28:42 -0500, [email]bs (AT) research (DOT) att.com[/email] (Bjarne Stroustrup)
wrote:

Quote:
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]);

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





PostPosted: Thu Dec 11, 2003 11:42 am    Post subject: Re: a[i] not equivalent to *(a+i)? Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2, 3, 4, 5  Next
Page 1 of 5

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.