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 

dereferencing the 'last+1' element of an array
Goto page 1, 2, 3, 4, 5, 6  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Sensorflo
Guest





PostPosted: Thu Nov 04, 2004 11:57 am    Post subject: dereferencing the 'last+1' element of an array Reply with quote



The annotated c++ reference manual says in 5.7 within an example:

One can refer to an element beyond the end of an erray, but it is
still an error to dereference such a pointer.
char a[10];
void f()
{ char* p = &a[10]; // p points to one past the end of a
*p = 999; // error
}

But how exactly is "dereferencing" defined? Isnt it the use of the
inderection operator * ? The standart says that a[b] is equal to
*((a)+(b)). Thus, in the example above, &a[10] expands to
&*((a)+(10)). Here I have the indirection operator. Thus the compiler
is allowed to dereference the expression ((a)+(10)), which points one
beyond the last element of the array. This would be an error. I think
the compiler doesnt have to recognize that &* is an null operation in
this case. And thus the example above woud not meet the standart. What
am I missing? I trust the example in my book, so I guess I am
missunderstanding something. What?

The standart doesnt define &* to be an null-operation (or idendity
operation? I dont know the exact word, but I guess you understand me).
I dont know exactly why (maybe because operators can be overloaded,
and then it would get messy if the standart would define &* as an
identy operation, but only for the buildin operators). I read this in
a newsgroupe article, the author of which was in the c++ standart
comitee.

Flo

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Ron Natalie
Guest





PostPosted: Fri Nov 05, 2004 3:14 am    Post subject: Re: dereferencing the 'last+1' element of an array Reply with quote



oncept.


Quote:
But how exactly is "dereferencing" defined? Isnt it the use of the
inderection operator * ?

Dereferencing means using accessing the value of the pointed to
object. * will do it, so will subscripting, so will the member
access operators (->).

Quote:
I think
the compiler doesnt have to recognize that &* is an null operation in
this case.

It might not generate code, but it's still logically a dereference.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Victor Bazarov
Guest





PostPosted: Fri Nov 05, 2004 3:22 am    Post subject: Re: dereferencing the 'last+1' element of an array Reply with quote



Sensorflo wrote:
Quote:
The annotated c++ reference manual says in 5.7 within an example:

One can refer to an element beyond the end of an erray, but it is
still an error to dereference such a pointer.
char a[10];
void f()
{ char* p = &a[10]; // p points to one past the end of a
*p = 999; // error
}

But how exactly is "dereferencing" defined? Isnt it the use of the
inderection operator * ?

Yes.

Quote:
The standart says that a[b] is equal to
*((a)+(b)). Thus, in the example above, &a[10] expands to
&*((a)+(10)). Here I have the indirection operator. Thus the compiler
is allowed to dereference the expression ((a)+(10)), which points one
beyond the last element of the array. This would be an error.

Right.

Quote:
I think
the compiler doesnt have to recognize that &* is an null operation in
this case.

There is no such requirement in the Standard, yes.

Quote:
And thus the example above woud not meet the standart.

The Standard says that only _evaluation_ of the expression (P)+1 where
(P) points to the last element of an array is OK. Any other use is
undefined. So, dereferencing is undefined, I guess. That still makes
the program well-formed, but causing undefined behaviour.

This is not unseen in books.

Quote:
What
am I missing? I trust the example in my book, so I guess I am
missunderstanding something. What?

Nothing. Books are written by people. Some people have something very
important to share with us, some just have too much time on their hands.
Therefore we have good books and bad books.

Quote:

The standart doesnt define &* to be an null-operation (or idendity
operation? I dont know the exact word, but I guess you understand me).

We understand you.

Quote:
I dont know exactly why (maybe because operators can be overloaded,

Exactly.

Quote:
and then it would get messy if the standart would define &* as an
identy operation, but only for the buildin operators). I read this in
a newsgroupe article, the author of which was in the c++ standart
comitee.

Well, some operators do behave differently already if they are for built-
in types or overloaded for UDTs. It wouldn't be too big of a deal to
actually define &* as a NOP for pointers. But I guess they just didn't
want to bother...

V

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Andrew Koenig
Guest





PostPosted: Fri Nov 05, 2004 3:23 am    Post subject: Re: dereferencing the 'last+1' element of an array Reply with quote

"Sensorflo" <spamadress (AT) bigfoot (DOT) com> wrote

Quote:
The annotated c++ reference manual says in 5.7 within an example:

One can refer to an element beyond the end of an erray, but it is
still an error to dereference such a pointer.
char a[10];
void f()
{ char* p = &a[10]; // p points to one past the end of a
*p = 999; // error
}

But how exactly is "dereferencing" defined? Isnt it the use of the
inderection operator * ? The standart says that a[b] is equal to
*((a)+(b)).

Yes: The example above is incorrect, although one might wish it otherwise.
It should read:

char* p = a + 10;


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
assaarpa
Guest





PostPosted: Fri Nov 05, 2004 3:23 am    Post subject: Re: dereferencing the 'last+1' element of an array Reply with quote

Quote:
{ char* p = &a[10]; // p points to one past the end of a

I would write that:

char* p = a + 10;

Just a matter of taste, but hope you find that easier to read as I did.

Quote:
But how exactly is "dereferencing" defined? Isnt it the use of the
inderection operator * ? The standart says that a[b] is equal to
*((a)+(b)).

That doesn't mean &a[10] expands to the following..

Quote:
Thus, in the example above, &a[10] expands to
&*((a)+(10)).

... but rather to a + 10. If I wanted to be absolutely sure and not look like
incompetent (like I do now!) I would bury my nose into the standard and look
what it says about address-of ( & ) operator and then get fame and glory. As
it is, just wrote inaccurate I-think-it-is-so nonsense.

-Mr.Poop



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Robert Kindred
Guest





PostPosted: Fri Nov 05, 2004 3:19 pm    Post subject: Re: dereferencing the 'last+1' element of an array Reply with quote


"Sensorflo" <spamadress (AT) bigfoot (DOT) com> wrote

Quote:
The annotated c++ reference manual says in 5.7 within an example:

One can refer to an element beyond the end of an erray, but it is
still an error to dereference such a pointer.
char a[10];
void f()
{ char* p = &a[10]; // p points to one past the end of a
*p = 999; // error
}

[]

The standart doesnt define &* to be an null-operation (or idendity
operation?
[]


In a pinch, I have actually had to use the above pair of operators, and it
was not a null operation, because the * was overloaded by shared_ptr. What
I really needed was a pointer to my object to pass to older code which did
not accept a smart pointer. I just had to remember not to do a delete on
the "wild" pointer.

Robert Kindred

Quote:

Flo

[ 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: Fri Nov 05, 2004 5:19 pm    Post subject: Re: dereferencing the 'last+1' element of an array Reply with quote

[email]spamadress (AT) bigfoot (DOT) com[/email] (Sensorflo) wrote:
Quote:

char a[10];
void f()
{ char* p = &a[10]; // p points to one past the end of a
*p = 999; // error
}

But how exactly is "dereferencing" defined? Isnt it the use of the
inderection operator * ? The standart says that a[b] is equal to
*((a)+(b)). Thus, in the example above, &a[10] expands to
&*((a)+(10)). Here I have the indirection operator. Thus the compiler
is allowed to dereference the expression ((a)+(10)), which points one
beyond the last element of the array. This would be an error.

This has been discussed in C forums before.
There is no undefined behaviour until an lvalue-to-rvalue
conversion (aka. an evaluation) is performed.
*(a + 10) is a valid lvalue expression. The operation &x does
NOT involve evaluating x. So &(*(a+10)) is OK.

For similar reasons,
#define offsetof(x,y) &((x *)0)->y
works.

It would be reasonable to apply similar conclusions to C++.

Btw, the C standard doesn't use the term "dereference", it uses
"indirect through" [a pointer]. But this makes no difference
essentially.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ali Çehreli
Guest





PostPosted: Fri Nov 05, 2004 5:20 pm    Post subject: Re: dereferencing the 'last+1' element of an array Reply with quote

"Sensorflo" <spamadress (AT) bigfoot (DOT) com> wrote

Quote:
The annotated c++ reference manual says in 5.7 within an example:

One can refer to an element beyond the end of an erray, but it is
still an error to dereference such a pointer.
char a[10];
void f()
{ char* p = &a[10]; // p points to one past the end of a
*p = 999; // error
}

There has been past discussions on the same subject, one about a similar
usage in TC++PL. If I am not mistaken, Stroustroup has changed his mind and
corrected those usages. Possibly in the books' errata... (?)

Quote:
Isnt it the use of the
inderection operator * ?

You are correct. The code should better be written as

char * p = &a[0] + 10;

Quote:
I trust the example in my book, so I guess I am
missunderstanding something.

No, in this case the example is wrong :)

Ali


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ivan Vecerina
Guest





PostPosted: Fri Nov 05, 2004 5:25 pm    Post subject: Re: dereferencing the 'last+1' element of an array Reply with quote

"Sensorflo" <spamadress (AT) bigfoot (DOT) com> wrote

Quote:
The annotated c++ reference manual says in 5.7 within an example:

One can refer to an element beyond the end of an erray, but it is
still an error to dereference such a pointer.
char a[10];
void f()
{ char* p = &a[10]; // p points to one past the end of a
*p = 999; // error
}
.....
I think
the compiler doesnt have to recognize that &* is an null operation in
this case. And thus the example above woud not meet the standart. What
am I missing? I trust the example in my book, so I guess I am
missunderstanding something. What?

Your understanding is correct. The first line above does formally lead
to undefined behavior -- that's how things are defined by the standard.
To be portable and correct, the line should be replaced with:
char* p = a+10;

In practice, I personally do not know of a platform where the original
expression will fail, so it is a common error. But an implementation
could choose to perform runtime bounds checks, or otherwise react
to the error.


hth -Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jonas Norberg
Guest





PostPosted: Fri Nov 05, 2004 5:27 pm    Post subject: Re: dereferencing the 'last+1' element of an array Reply with quote

Sensorflo wrote:

Quote:
But how exactly is "dereferencing" defined? Isnt it the use of the
inderection operator * ?

Dereferencing a pointer/reference is using the value it refers to. This
usually (always?) involves reading from or writing to the adress.

An example of dereferencing using '->':

struct A{ int c; };
A a[10];
A *ptr = a + 10; // points outside

ptr->c = 999; // error

The point is that you can dereference a pointer/reference in many ways,
not only by a explicit '*' operator.

One error is calling member functions on invalid object-pointers, where
the possible dereferencing actually happens inside the member function.
__
Jonas Norberg


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ali Cehreli
Guest





PostPosted: Sat Nov 06, 2004 2:10 pm    Post subject: Re: dereferencing the 'last+1' element of an array Reply with quote

On Fri, 05 Nov 2004 10:19:39 -0500, Robert Kindred wrote:

Quote:
The standart doesnt define &* to be an null-operation (or idendity
operation?
[]

In a pinch, I have actually had to use the above pair of operators, and it
was not a null operation, because the * was overloaded by shared_ptr. What
I really needed was a pointer to my object to pass to older code which did
not accept a smart pointer.

If that's boost::shared_ptr, you could use the get method:

older_code(my_shared_ptr.get());

Ali


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ali Cehreli
Guest





PostPosted: Sat Nov 06, 2004 2:11 pm    Post subject: Re: dereferencing the 'last+1' element of an array Reply with quote

On Fri, 05 Nov 2004 12:19:50 -0500, Old Wolf wrote:

Quote:
spamadress (AT) bigfoot (DOT) com (Sensorflo) wrote:

char a[10];
void f()
{ char* p = &a[10]; // p points to one past the end of a
*p = 999; // error
}

But how exactly is "dereferencing" defined? Isnt it the use of the
inderection operator * ? The standart says that a[b] is equal to
*((a)+(b)). Thus, in the example above, &a[10] expands to
&*((a)+(10)). Here I have the indirection operator. Thus the compiler
is allowed to dereference the expression ((a)+(10)), which points one
beyond the last element of the array. This would be an error.

This has been discussed in C forums before.

You can find two such discussions if you search for

"Ali Cehreli" "Carlos Moreno" Stroustrup

on groups.google.com. Here is what Stroustrup thinks about the issue:

http://www.research.att.com/~bs/3rd_issues.html

Scroll down on that page to 'pg 42'...

Quote:
There is no undefined behaviour until an lvalue-to-rvalue
conversion (aka. an evaluation) is performed.
*(a + 10) is a valid lvalue expression.

But there is no object at location 10. operator* does
reference a non-existent object.

Quote:
The operation &x does
NOT involve evaluating x. So &(*(a+10)) is OK.

The undefined behavior comes into play before operator& is used.

Quote:
For similar reasons,
#define offsetof(x,y) &((x *)0)->y
works.

That works only because the compiler implementor knows that
it works. Otherwise, that is undefined behavior as well: In
this case, operator-> is applied to a non-existent object at
location 0.

Quote:
It would be reasonable to apply similar conclusions to C++.

What I said above applies for both C and C++.

Ali


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Tom Widmer
Guest





PostPosted: Sat Nov 06, 2004 2:12 pm    Post subject: Re: dereferencing the 'last+1' element of an array Reply with quote

On 4 Nov 2004 06:57:11 -0500, [email]spamadress (AT) bigfoot (DOT) com[/email] (Sensorflo)
wrote:

Quote:
The annotated c++ reference manual says in 5.7 within an example:

One can refer to an element beyond the end of an erray, but it is
still an error to dereference such a pointer.
char a[10];
void f()
{ char* p = &a[10]; // p points to one past the end of a
*p = 999; // error
}

But how exactly is "dereferencing" defined? Isnt it the use of the
inderection operator * ?

The C99 standard explicity defines &a[10] to be equivalent to a + 10.
It also defines "&*a" to be equivalent to "a". However the C++
standard doesn't have either of these features, and &a[10] is
equivalent to &*(a + 10), which has undefined behaviour.

Tom

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Hyman Rosen
Guest





PostPosted: Sun Nov 07, 2004 12:06 pm    Post subject: Re: dereferencing the 'last+1' element of an array Reply with quote

Tom Widmer wrote:
Quote:
The C99 standard explicity defines &a[10] to be equivalent to a + 10.
It also defines "&*a" to be equivalent to "a". However the C++
standard doesn't have either of these features, and &a[10] is
equivalent to &*(a + 10), which has undefined behaviour.

C++ has to contecnd with potential user-defined implementations of
operator&, operator[], and operator*, so it's not as easy for it to
do what C99 does.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
assaarpa
Guest





PostPosted: Sun Nov 07, 2004 12:12 pm    Post subject: Re: dereferencing the 'last+1' element of an array Reply with quote

Quote:
standard doesn't have either of these features, and &a[10] is
equivalent to &*(a + 10), which has undefined behaviour.

I am sick and tired of this bullshit, my experience screams against such
nonsense so time to look what the Standard says about that.

5.19.4

An address constant expression is a pointer to an lvalue designating an
object of static storage duration, a string literal (2.13.4), or a function.
The pointer shall be created explicitly, using the unary & operator, or
implicitly using a non-type template parameter of pointer type, or using an
expression of array (4.2) or function (4.3) type. The subscripting operator
[] and the class member access . and -> operator, the & and * unary
operators, and pointer casts (except dynamic_casts 5.2.7) can be used in the
creation of an address constant expression, BUT THE VALUE OF AN OBJECT SHALL
NOT BE ACCESSED BY THE USE OF THESE OPERATORS. If hte subscripting operator
is used, one of its operands shall be an integral constant expression. An
expression that designates the address of a member or base class of a
non-POD class object (clause 9) is not an address constant expression
(12.7). Function calls shall not be used in an address constant expression,
even if the function is inline and has a reference return type.

I think that settles it pretty clearly: taking address of object boils down
to simple pointer arithmetic and no need to think if some object exists or
not I don't see how this is undefined behaviour. However, using the pointer
may be as the address might be out of bounds or some other implementation
specific/dependent thing and that is where the undefined behaviour is
invoked.

In otherwords: computing the address is well defined. Using it may be
undefined.

-Mr.Poop




[ 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, 6  Next
Page 1 of 6

 
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.