By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,171 Members | 1,037 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,171 IT Pros & Developers. It's quick & easy.

Negative indices to a vector: Valid?

P: n/a

Hello,

I have the following code:

#define N 99
double *ptr;
double *storage;
int index;

storage = calloc(N , sizeof(double));
ptr = &storage[N/2];
...
...
...
free(storage);
Now ptr points into the middle of the allocated memory area, and I can
access elements in the array as ptr[index], where index is a *signed*
variable which can take the values -N/2,...N/2. Is this legal
behaviour? Or should the index operator only be given unsigned
arguments?

I have tried using a couple of different compilers on Linux and IRIX,
and it seems to work, but it does give me a slightly queasy feeling.
Regards

Joakim

--
Joakim Hove
hove AT ntnu.no /
Tlf: +47 (55 5)8 27 13 / Stabburveien 18
Fax: +47 (55 5)8 94 40 / N-5231 Paradis
http://www.ift.uib.no/~hove/ / 55 91 28 18 / 92 68 57 04
Dec 22 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
This is perfectly legal. The array index is treated as a signed integer
in C.

a[i] is a shorthand way of writing
a + sizeof(a)*i

Thus if i is negative, the final entry addressed would be before a[0].

--
EventStudio System Designer 2.5 - http://www.EventHelix.com/EventStudio
Sequence Diagram Based Real-time and Embedded System Design Tool

Dec 22 '05 #2

P: n/a
Joakim Hove wrote:
Hello,

I have the following code:

#define N 99
double *ptr;
double *storage;
int index;

storage = calloc(N , sizeof(double));
All bits 0 (which is what calloc provides) is *not* guaranteed to
represent a floating point 0, it could even be a trap representation.
Also, using "sizeof *storage" would be better than "sizeof(double)"
because if the type ever changes (say, to long double) then you will
still get the correct amount of space.
ptr = &storage[N/2];
...
...
...
free(storage);
Now ptr points into the middle of the allocated memory area, and I can
access elements in the array as ptr[index], where index is a *signed*
variable which can take the values -N/2,...N/2. Is this legal
behaviour? Or should the index operator only be given unsigned
arguments?
What you are doing is completely legal. You could even do it if you were
using an array. Obviously, you have to be careful to ensure you don't go
off the end of the allocated space which can require a little more thought.
I have tried using a couple of different compilers on Linux and IRIX,
and it seems to work, but it does give me a slightly queasy feeling.


You are right to ask rather than relying on experimental results, since
there are "illegal" things that will "work" on some platforms but fail
on others, one of the classic (IMHO) examples of this being modifying
string literals.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Dec 22 '05 #3

P: n/a
Joakim Hove wrote:

Hello,

I have the following code:

#define N 99
double *ptr;
double *storage;
int index;

storage = calloc(N , sizeof(double));
ptr = &storage[N/2];
...
...
...
free(storage);

Now ptr points into the middle of the allocated memory area, and I can
access elements in the array as ptr[index], where index is a *signed*
variable which can take the values -N/2,...N/2. Is this legal
behaviour?


Only if by "Now", you mean before:

free(storage);

--
pete
Dec 22 '05 #4

P: n/a
Joakim Hove wrote:
Hello,

I have the following code:

#define N 99
double *ptr;
double *storage;
int index;

storage = calloc(N , sizeof(double));
ptr = &storage[N/2];
...
...
...
free(storage);
Now ptr points into the middle of the allocated memory area, and I can
access elements in the array as ptr[index], where index is a *signed*
variable which can take the values -N/2,...N/2. Is this legal
behaviour? Or should the index operator only be given unsigned
arguments?


Legal, provided N is odd (as shown).

However, do not be fooled into thinking that "just any"
offset will work. The above is all right because `ptr' does
in fact point into the allocated area. The language guarantees
that `ptr = &storage[k]' will work for all k between 0 and N
(inclusive at both ends), but not for k outside that range.
You may occasionally encounter `ptr = &storage[-1]' as part of
an attempt to imitate the 1-based arrays of Fortran, say, but
such code is incorrect and need not work at all.

--
Eric Sosman
es*****@acm-dot-org.invalid
Dec 22 '05 #5

P: n/a
>This is perfectly legal. The array index is treated as a signed integer
in C.

a[i] is a shorthand way of writing
a + sizeof(a)*i


No, a[i] is a shorthand way of writing *(a + i). It's also equivalent
to i[a].

It may also be considered as a shorthand way of writing
*(a addl (sizeof(a) * i)), where addl is an assembly-language
addition operator.

It is allowed for i to be negative provided the storage referred
to exists.

Gordon L. Burditt
Dec 22 '05 #6

P: n/a
Gordon Burditt wrote:
This is perfectly legal. The array index is treated as a signed integer
in C.

a[i] is a shorthand way of writing
a + sizeof(a)*i
No, a[i] is a shorthand way of writing *(a + i). It's also equivalent
to i[a].


Yes.
It may also be considered as a shorthand way of writing
*(a addl (sizeof(a) * i)), where addl is an assembly-language
addition operator.


I think it should be sizeof(*a), instead of sizeof a.

--
pete
Dec 22 '05 #7

P: n/a

Thanks to all of you who answered. It makes my code look much nicer,
so I am grateful that I can rely on this approach.
Joakim

--
Joakim Hove
hove AT ntnu.no /
Tlf: +47 (55 5)8 27 13 / Stabburveien 18
Fax: +47 (55 5)8 94 40 / N-5231 Paradis
http://www.ift.uib.no/~hove/ / 55 91 28 18 / 92 68 57 04
Dec 22 '05 #8

P: n/a
> No, a[i] is a shorthand way of writing *(a + i). It's also equivalent
to i[a].


Agreed. Pointer arithmatic internally multiples to take care of the
sizeof.

--
EventStudio System Designer 2.5 - http://www.EventHelix.com/EventStudio
Sequence Diagram Based System Design and Object Modeling Tool

Dec 24 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.