Velocity Reviews > Decrement a given pointer.

# Decrement a given pointer.

Michael Press
Guest
Posts: n/a

 07-08-2013
Given a pointer, p, can I set pm1 = p-1 and use pm1
without worrying that an implementation will object
or do other than what one expects? The idea is to
get offset one arrays, e.g.,

void
f(int *p, int l)
{
int i;
int t;
int *pm1 = p - 1;

for(i = 1; i <= l; i++)
t = pm1[i];
}

int a[] = {1, 2, 3};
int na = sizeof a / sizeof *a;

void
doit(void)
{
int *b = a;

f(a, na);
f(b, na);
}

--
Michael Press

Keith Thompson
Guest
Posts: n/a

 07-08-2013
Michael Press <(E-Mail Removed)> writes:
> Given a pointer, p, can I set pm1 = p-1 and use pm1
> without worrying that an implementation will object
> or do other than what one expects? The idea is to
> get offset one arrays, e.g.,
>
> void
> f(int *p, int l)
> {
> int i;
> int t;
> int *pm1 = p - 1;
>
> for(i = 1; i <= l; i++)
> t = pm1[i];
> }
>
> int a[] = {1, 2, 3};
> int na = sizeof a / sizeof *a;
>
> void
> doit(void)
> {
> int *b = a;
>
> f(a, na);
> f(b, na);
> }

No. Given a pointer to an array element, you can safely construct a
pointer to any element of the array. You can also safely construct a
pointer just past the end of the array, but you can't dereference it.
Using pointer arithmetic to construct a pointer outside the bounds of
the array has undefined behavior. (A single object is treated as a
one-element array for purposes of pointer arithmetic.)

It's fairly likely to work on most systems, but it's not guaranteed.

I seem to recall that the book "Numerical Recipes in C" used this
technique to translate Fortran code into C.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Joe Pfeiffer
Guest
Posts: n/a

 07-08-2013
Michael Press <(E-Mail Removed)> writes:

> Given a pointer, p, can I set pm1 = p-1 and use pm1
> without worrying that an implementation will object
> or do other than what one expects? The idea is to
> get offset one arrays, e.g.,

<snip>

Keith has already given what I expect is the right answer to your
question, but I'd go on to ask "why?". Unless there's a *really* good
reason, you should simply use the language as designed.

Having said that, I'll mention that I have occasion to use what amount
to offset 1 arrays on a current project: I'm obtaining altimeter data
from an altimeter that has a parameter that goes from 1 to 9; it seems
less error-prone to me to use a 10 element array and just waste element
0 than to mess with macros or other code to add and subract 1 from an
index in multiple places. But you'll notice that this approach to it
doesn't depend on tricky code having undefined behavior do the right
thing.

Siri Cruise
Guest
Posts: n/a

 07-08-2013
In article <(E-Mail Removed)>, Keith Thompson <(E-Mail Removed)>
wrote:

> It's fairly likely to work on most systems, but it's not guaranteed.

Some CPUs use address registers and check address validity when the address
computed rather than waiting for address load. If the array is at the beginning
some memory partition, these kinds of CPUs can get an address fault.
--
Mommy is giving the world some kind of bird.
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted.
NSA CIA Constitution patriot terrorism freedom Snowden Paid Maternity Leave

Eric Sosman
Guest
Posts: n/a

 07-09-2013
On 7/8/2013 7:12 PM, Michael Press wrote:
> Given a pointer, p, can I set pm1 = p-1 and use pm1
> without worrying that an implementation will object
> or do other than what one expects? The idea is to
> get offset one arrays, e.g.,
> [...]

This is Question 6.17 on the comp.lang.c Frequently
Asked Questions (FAQ) page at <http://www.c-faq.com/>.

--
Eric Sosman
(E-Mail Removed)d

Ian Collins
Guest
Posts: n/a

 07-09-2013
Siri Cruise wrote:
> In article <(E-Mail Removed)>, Keith Thompson <(E-Mail Removed)>
> wrote:
>
>> It's fairly likely to work on most systems, but it's not guaranteed.

>
> Some CPUs use address registers and check address validity when the address
> computed rather than waiting for address load. If the array is at the beginning
> some memory partition, these kinds of CPUs can get an address fault.

Not in the context of the OP, the address p-1 was never dereferenced.

--
Ian Collins

Eric Sosman
Guest
Posts: n/a

 07-09-2013
On 7/8/2013 9:14 PM, Ian Collins wrote:
> Siri Cruise wrote:
>> In article <(E-Mail Removed)>, Keith Thompson
>> <(E-Mail Removed)>
>> wrote:
>>
>>> It's fairly likely to work on most systems, but it's not guaranteed.

>>
>> Some CPUs use address registers and check address validity when the
>> computed rather than waiting for address load. If the array is at the
>> beginning
>> some memory partition, these kinds of CPUs can get an address fault.

>
> Not in the context of the OP, the address p-1 was never dereferenced.

Even computing it (trying to compute it) yields undefined
behavior. FAQ 6.17.

--
Eric Sosman
(E-Mail Removed)d

Siri Cruise
Guest
Posts: n/a

 07-09-2013
In article <(E-Mail Removed)>,
Ian Collins <(E-Mail Removed)> wrote:

> Siri Cruise wrote:
> > In article <(E-Mail Removed)>, Keith Thompson <(E-Mail Removed)>
> > wrote:
> >
> >> It's fairly likely to work on most systems, but it's not guaranteed.

> >
> > Some CPUs use address registers and check address validity when the address
> > computed rather than waiting for address load. If the array is at the
> > beginning
> > some memory partition, these kinds of CPUs can get an address fault.

>
> Not in the context of the OP, the address p-1 was never dereferenced.

It's not guarenteed to work because some CPUs validate addresses on computation
before dereference.
--
Mommy is giving the world some kind of bird.
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted.
NSA CIA Constitution patriot terrorism freedom Snowden Paid Maternity Leave

Keith Thompson
Guest
Posts: n/a

 07-09-2013
Ian Collins <(E-Mail Removed)> writes:
> Siri Cruise wrote:
>> In article <(E-Mail Removed)>, Keith Thompson <(E-Mail Removed)>
>> wrote:
>>
>>> It's fairly likely to work on most systems, but it's not guaranteed.

>>
>> Some CPUs use address registers and check address validity when the
>> address computed rather than waiting for address load. If the array
>> is at the beginning some memory partition, these kinds of CPUs can
>> get an address fault.

>
> Not in the context of the OP, the address p-1 was never dereferenced.

Siri Cruise said that the validity of the address is checked when it's
computed, not when it's dereferenced, so yes, that kind of CPU would get

(Which is consistent with my statement, since most CPUs don't do that.
Still, I certainly don't recommend counting on that.)

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

glen herrmannsfeldt
Guest
Posts: n/a

 07-09-2013
Siri Cruise <(E-Mail Removed)> wrote:
> In article <(E-Mail Removed)>,

(snip on generating p-1 where p is a pointer to something)

>> Not in the context of the OP, the address p-1 was never
>> dereferenced.

> It's not guarenteed to work because some CPUs validate addresses
> on computation before dereference.

Do you know of any actual such CPUs in current use?

The most popular CPU that uses anything similar wraps the
address on computation, such that it works.

I used protected mode on the 80286 in OS/2, and then on the 486 for
a while before OS/2 2.0 came out. On the 80286 in protected mode,
addresses consist of a segment selector, selecting a segment descriptor,
and a 16 bit offset into the segment. If you subtract, the offset will
wrap, and when you add one again, will wrap back again.

The CPU will validate a segment selector when loaded into a segment
register, except that segment 0 is the null segment selector.
(A special case in hardware.)

If a system does bounds checking, it is possible that the
bounds check will notice, but even then it is likely done
only at dereference.

But yes, it violates the standard but most likely will work.

-- glen

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is OffTrackbacks are On Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post tahir rauf C Programming 12 04-29-2011 11:44 PM Casey Hawthorne C Programming 385 04-04-2010 02:11 AM 2Barter.net C++ 0 12-13-2006 02:56 AM Lord0 Java 1 04-19-2006 04:54 PM chiara C Programming 6 10-06-2005 01:43 AM