473,323 Members | 1,622 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,323 software developers and data experts.

pointers and beginnings of arrays


I seem to have lost my copy of the ANSI C standard. Is this code legal?

/* p points somewhere in a string that is known to contain
an 'a' at or before where p points. We want to change
this 'a' to a 'b'. */
while ( *p-- != 'a' )
;
*++p = 'b';

If the only 'a' at or before the initial place p points to is the first
character of the string, the last p-- will be doing -- on a pointer to
the first character of the string, but it is then incremented with ++
before being used.

Another example. Again, p points to a string, this time known to
contain an 'a', but this time at or after where p points. To change it
to a 'b':

--p;
while ( *++p != 'a' )
;
*p = 'b';

If p started at the beginning of the string, this would --p to before
the string, then immediately ++p back into the string.

I seem to remember that you can't take the address of elements of an
array before the 0th element, but I don't recall if using -- on a
pointer counts as taking the address of something.

--
--Tim Smith
May 23 '07 #1
3 1306
Tim Smith wrote, On 23/05/07 07:37:
I seem to have lost my copy of the ANSI C standard. Is this code legal?
I refer the honourable gentleman to http://clc-wiki.net/ where, in the
obvious place, you will find pointers to free downloads of various
drafts of the C standard.

<snip>
I seem to remember that you can't take the address of elements of an
array before the 0th element, but I don't recall if using -- on a
pointer counts as taking the address of something.
You are not allowed to calculate an address before the start of the
array. You are allowed to calculate the address one passed the end
because the standard gives you special dispensation, although you
obviously cannot dereference it.

Not allowed and cannot being informal terms indicating if you try it
invokes undefined behaviour.
--
Flash Gordon
May 23 '07 #2
In article <re**********************************@news.superne ws.com>
Tim Smith <re************@mouse-potato.comwrote:
>I seem to have lost my copy of the ANSI C standard. Is this code legal?
Indeed, in the case you describe, it is not:
/* p points somewhere in a string that is known to contain
an 'a' at or before where p points. We want to change
this 'a' to a 'b'. */
while ( *p-- != 'a' )
;
*++p = 'b';

If the only 'a' at or before the initial place p points to is the first
character of the string, the last p-- will be doing -- on a pointer to
the first character of the string, but it is then incremented with ++
before being used.
This is technically undefined, although it tends to work in practice
on "real systems".

You can re-code the above as:

while (*p != 'a')
p--;
*p = 'b';

to remove the bug.
>Another example. Again, p points to a string, this time known to
contain an 'a', but this time at or after where p points. To change it
to a 'b':

--p;
while ( *++p != 'a' )
;
*p = 'b';

If p started at the beginning of the string, this would --p to before
the string, then immediately ++p back into the string.
Again, technically illegal.
>I seem to remember that you can't take the address of elements of an
array before the 0th element, but I don't recall if using -- on a
pointer counts as taking the address of something.
It does.

The second example can be recoded as the obvious:

while (*p != 'a')
p++;
*p = 'b';

or the less-obvious (but still legal, provided there is some 'a' in
range):

while (*p++ != 'a')
continue;
*--p = 'b';

This second one is legal, despite going "one past the end" in some
cases, because "going one past the end" is explicitly allowed, so
that loops like:

for (p = arr, i = 0; i < n; p++, i++)
... operate on *p ...

remained defined in C89. On those rare "real systems" on which
out of bounds pointer arithmetic is actually trapped, the cost of
making "one past the end" work is generally one byte (or one machine
word) of extra storage at the end of a segment, while the cost of
making "one before the start" work would have been "as many bytes
(or machine words) as needed based on sizeof *p".

(This falls out naturally since, if sizeof *p is 1000, "p++" turns
into "add #1000,reg" and "p--" turns into "sub #1000,reg", all
assuming the machine works in C-bytes natively of course. When
reg is near the end of the segment, pointing to the last valid
object, adding 1000 puts it one byte past the last valid object --
so the implementation has to sneak in an extra "pad" byte at the
end of the segment -- but when reg is right at the beginning,
pointing to the first valid object, subtracting 1000 puts it 1000
bytes before the start, so the implementation would have had to
insert 1000 pad bytes at the front of the segment.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
May 24 '07 #3
Tim Smith wrote:
>
I seem to have lost my copy of the ANSI C standard. Is this code
legal?

/* p points somewhere in a string that is known to contain
an 'a' at or before where p points. We want to change
this 'a' to a 'b'. */
while ( *p-- != 'a' )
;
*++p = 'b';

If the only 'a' at or before the initial place p points to is the
first character of the string, the last p-- will be doing -- on a
pointer to the first character of the string, but it is then
incremented with ++ before being used.
So change the code:

while (*p != 'a') --p;
*p = 'b';

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

May 24 '07 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

19
by: Thomas Matthews | last post by:
Hi, Given a structure of pointers: struct Example_Struct { unsigned char * ptr_buffer; unsigned int * ptr_numbers; }; And a function that will accept the structure:
11
by: Linny | last post by:
Hi, I need some help in declaring an array of pointers to array of a certain fixed size. I want the pointers to point to arrays of fixed size only (should not work for variable sized arrays of the...
79
by: Me | last post by:
Just a question/observation out of frustration. I read in depth the book by Peter Van Der Linden entitled "Expert C Programming" (Deep C Secrets). In particular the chapters entitled: 4: The...
6
by: Carl-Olof Almbladh | last post by:
Already in the 1st edition of the "White book", Kerigham and Ritchie states the "C is a general purpose language". However, without what is usually called "assumed size arrays" and built-in...
4
by: Richard Hayden | last post by:
Hi, Why does gcc (3.3.2) give me a 'initialization from incompatible pointer type' warning when compiling: int main(int argc, char** argv) { int testa; int** testp = testa; }
5
by: Paminu | last post by:
Why make an array of pointers to structs, when it is possible to just make an array of structs? I have this struct: struct test { int a; int b;
36
by: raphfrk | last post by:
I have the following code: char buf; printf("%lp\n", buf); printf("%lp\n", &buf); printf("%lp\n", buf); printf("%lp\n", buf); printf("%d\n", buf-buf);
6
by: joelperr | last post by:
Hello, I am attempting to separate a two dimensional array into two one-dimensional arrays through a function. The goal of this is that, from the rest of the program, a data file consisting of...
8
by: Piotrek | last post by:
Hi, Like almost all of beginners I have problem understanding pointers. Please, look at this piece of code, and please explain me why myswap function doesn't work as it's supposed to do, whereas...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.