Can I tab[-1] ?

F

fir

Can I use c arrays in such way tab[-1] or tab[-1][-1] (I mean when index is below zero)?

Also - I think if try to use some way of optimization
where instead of checking some edge values like

if(x>=0 && x<500 && y>=0 && y<500)
tab[y][x] = 1;

alloc some edge ram and do not bother about x=-1 or x=tab_max_x+1

but here it would be convenient to cast some pointer ot type tab[500][500] 'into' wider_tab[502][502]
in such way that tab[0][0] wolul correspond to wider_tab[1][1] (and tab[-1][-1] to wider_tab[0][0])

Can I get something like that? (If not I am sad)
 
G

glen herrmannsfeldt

fir said:
Can I use c arrays in such way tab[-1] or tab[-1][-1]
(I mean when index is below zero)?
Also - I think if try to use some way of optimization
where instead of checking some edge values like
if(x>=0 && x<500 && y>=0 && y<500)
tab[y][x] = 1;
alloc some edge ram and do not bother about x=-1 or x=tab_max_x+1

Not with actual arrays, but you can with pointers and arrays
of pointers.
but here it would be convenient to cast some pointer ot type
tab[500][500] 'into' wider_tab[502][502] in such way that
tab[0][0] wolul correspond to wider_tab[1][1]
(and tab[-1][-1] to wider_tab[0][0])
Can I get something like that? (If not I am sad)

There is much discussion about pointers outside the allocated
space, such that the offset is inside. In this case, though,
the pointer is inside the allocated space, such that adding -1
is still inside.

-- glen
 
F

fir

W dniu czwartek, 20 grudnia 2012 08:43:49 UTC+1 użytkownik glen herrmannsfeldt napisał:
fir said:
Can I use c arrays in such way tab[-1] or tab[-1][-1]
(I mean when index is below zero)?
Also - I think if try to use some way of optimization
where instead of checking some edge values like
if(x>=0 && x<500 && y>=0 && y<500)
tab[y][x] = 1;


alloc some edge ram and do not bother about x=-1 or x=tab_max_x+1
Not with actual arrays, but you can with pointers and arrays
of pointers.


but here it would be convenient to cast some pointer ot type
tab[500][500] 'into' wider_tab[502][502] in such way that
tab[0][0] wolul correspond to wider_tab[1][1]
(and tab[-1][-1] to wider_tab[0][0])


Can I get something like that? (If not I am sad)



There is much discussion about pointers outside the allocated
space, such that the offset is inside. In this case, though,
the pointer is inside the allocated space, such that adding -1
is still inside.

you sure i cant do it with some static array[][] cast? I want such syntax tab[][] and also
i need natural coordinates 0-500 for centre plus -1 and 501 for additional border, also I wnt efficiency - adequate simple casting would be the best, though i do anderstand that i should cast on something like tab[502][502]
with somme offset (not tab[500][500]) and then
used it in tab[-1 to 501 included] so I just need recast tab[502][502] a 503 fields further

as to array of pointers with same syntax of usage t[j] - is it more efficient or less
(it is very important question and i still not sure)
 
P

Philip Lantz

fir said:
Also - I think if try to use some way of optimization
where instead of checking some edge values like

if(x>=0 && x<500 && y>=0 && y<500)
tab[y][x] = 1;

alloc some edge ram and do not bother about x=-1 or x=tab_max_x+1

but here it would be convenient to cast some pointer to type
tab[500][500] 'into' wider_tab[502][502] in such way that
tab[0][0] would correspond to wider_tab[1][1] (and tab[-1][-1]
to wider_tab[0][0])

int wider_tab[501*501+1];
int (*tab)[500] = (int (*)[500])&wider_tab[500+1];

tab[0][0] is wider_tab[501]
tab[1][0] is wider_tab[1001]
tab[500][500] is wider_tab[501*501]
tab[-1][-1] is wider_tab[0]

There is a caveat: It's possible that the standard allows (int [500]) to
have a stricter alignment requirement than (int [502*502]), which would
mean that the cast isn't guaranteed to behave. I'm not convinced that
it's allowed, and even if it is, I am confident that no implementation
actually has such a requirement.

It's also possible that an implementation for x86 in huge model (where
arrays can span multiple segments), or similar architectures, could have
trouble with this, if the compiler was doing some very sophisticated
optimizations based on knowledge of how the array boundaries line up
with with segment boundaries. The normal brute force approach to huge
model shouldn't have any problem with it, though.
 
G

glen herrmannsfeldt

fir said:
fir said:
Can I use c arrays in such way tab[-1] or tab[-1][-1]
(I mean when index is below zero)?
(snip)

(snip, then I wrote)
Not with actual arrays, but you can with pointers and arrays
of pointers.
but here it would be convenient to cast some pointer ot type
tab[500][500] 'into' wider_tab[502][502] in such way that
tab[0][0] wolul correspond to wider_tab[1][1]
(and tab[-1][-1] to wider_tab[0][0])
(snip)

you sure i cant do it with some static array[][] cast?
I want such syntax tab[][] and also i need natural coordinates
0-500 for centre plus -1 and 501 for additional border,
also I wnt efficiency - adequate simple casting would be the best,
though i do anderstand that i should cast on something
like tab[502][502] with somme offset (not tab[500][500]) and then
used it in tab[-1 to 501 included] so I just need recast
tab[502][502] a 503 fields further

In the 1D case, you set a pointer to element 1, then all will
be off by one.

int tab1[503];
int *tab=tab+1;

Now tab[-1] through tab[501] exist. In most cases, the speed should
be the same.
as to array of pointers with same syntax of usage
t[j] - is it more efficient or less
(it is very important question and i still not sure)


In the 2D case, you have an array of pointers to arrays, which
you can either generate pointers to existing arrays, or dynamically
allocate them:

int **tab2;
tab2=malloc(503*sizeof(*tab2))+1;
for(i=-1;i<502;i++) tab2=malloc(503*sizeof(**tab2))+1;

Often it is done this way to allow for dynamic allocation, and
not for efficiency reasons. It is a little hard to say which is
more efficient, as it depends much on the processor, memory cache,
and instruction overlap.

(Note that -1 through 501 is 503 elements, not 502.)

-- glen
 
G

glen herrmannsfeldt

(snip)
alloc some edge ram and do not bother about x=-1 or x=tab_max_x+1
but here it would be convenient to cast some pointer to type
tab[500][500] 'into' wider_tab[502][502] in such way that
tab[0][0] would correspond to wider_tab[1][1] (and tab[-1][-1]
to wider_tab[0][0])
(snip)

int wider_tab[501*501+1];
int (*tab)[500] = (int (*)[500])&wider_tab[500+1];
tab[0][0] is wider_tab[501]
tab[1][0] is wider_tab[1001]
tab[500][500] is wider_tab[501*501]
tab[-1][-1] is wider_tab[0]
There is a caveat: It's possible that the standard allows (int [500]) to
have a stricter alignment requirement than (int [502*502]), which would
mean that the cast isn't guaranteed to behave. I'm not convinced that
it's allowed, and even if it is, I am confident that no implementation
actually has such a requirement.

Sometimes it is nice to have something aligned higher than the
normal alignment, such as when using SSE modes that require 16 byte
alignment. In most cases, though, it is up to the programmer to keep
things aligned, not the compiler.
It's also possible that an implementation for x86 in huge model (where
arrays can span multiple segments), or similar architectures, could have
trouble with this, if the compiler was doing some very sophisticated
optimizations based on knowledge of how the array boundaries line up
with with segment boundaries.

Yes, but in that case an array of large model pointers is a better choice.
The normal brute force approach to huge model shouldn't have any
problem with it, though.

Besides, since the 80386 segments are up to 4GB, and pretty much no
systems support even large model in 32 bit mode.

(Yes, I did much work on the 80286 using arrays of far pointers.)

-- glen
 
G

glen herrmannsfeldt

(snip)
I'm less confident that using a -1 as an index is guaranteed to work,
but I think it might be.

I believe it pretty much has to work. The other way around, subtracting
from a pointer to allow the low end of an array to be 1 is not
guaranteed to work, but was used in "Numerical Recipes in C" to make
translation from Fortran to C easier.
I'm less convinced that it's a good idea, though...

Hard to say.

-- glen
 
S

Shao Miller

There is a caveat: It's possible that the standard allows (int [500]) to
have a stricter alignment requirement than (int [502*502]), which would
mean that the cast isn't guaranteed to behave. I'm not convinced that
it's allowed, and even if it is, I am confident that no implementation
actually has such a requirement.

Confidence: Agreed.

C11's 6.2.8p4 seems to suggest that possible alignments are really
derived from fundamental types.

It'd seem odd if 'malloc(sizeof (int[502 * 502]))' had to worry about
satisfying the possibility that you might be overallocating, but really
interested in using the storage for an 'int[500]' with a stricter
requirement than an 'int[502 * 502]'.

- Shao Miller
 
F

fir

W dniu czwartek, 20 grudnia 2012 10:16:48 UTC+1 użytkownik glen herrmannsfeldt napisał:
Hard to say.

not to much hard to say ;-) it is good

can be usefull as in my example of :

x, y are random coordinates from x: -10 to 650, y: -10 to 500, there are large amounts of them only some are out of 0-640 0-480

you dont want to if(x>=0 && x<640 && y>=0 && y<480) ... on thousands ofthem just need to alloc little more and if you can 'recast' it
you can use natural coordinates (same as with pure method with if() checking/clipping,

so imo it is welcome in c
 
S

Shao Miller

Can I use c arrays in such way tab[-1] or tab[-1][-1] (I mean when index is below zero)?

I'd say it depends on the declaration. It is not clear from this
question what the types of 'tab[-1]' or 'tab[-1][-1]' are expected to be.
Also - I think if try to use some way of optimization
where instead of checking some edge values like

if(x>=0 && x<500 && y>=0 && y<500)
tab[y][x] = 1;

alloc some edge ram and do not bother about x=-1 or x=tab_max_x+1

I don't see any allocation. Could you share the bit of code that does
the allocation?
but here it would be convenient to cast some pointer ot type tab[500][500] 'into' wider_tab[502][502]
in such way that tab[0][0] wolul correspond to wider_tab[1][1] (and tab[-1][-1] to wider_tab[0][0])

Can I get something like that? (If not I am sad)

I'd say it depends on the declarations involved. It is not clear if you
are working with an array of pointers or not, for example.

You might or might not be interested in "Multi-Dimensional Array
Simulator" at http://www.iso-9899.info/wiki/Code_snippets

- Shao Miller
 
S

Shao Miller

I think you can do something like this:

int a[12][12];

void f()
{
int (*b)[10][12]; // note: use only 0..9 in second index

b = (int (*)[10][12])&(a[1][1]);

(*b)[2][2] = 3;
}

Given that the array layout is standardized, I *think* that doesn't
violate any rules. You'd have a row and column of "pad" around the
10x10 array.

I'm less confident that using a -1 as an index is guaranteed to work,
but I think it might be.

I'm less convinced that it's a good idea, though...

(*b)[-1]
*(*b - 1)

In this context, '*b' has type 'int[10][12]' but yields an 'int(*)[12]'.
Regardless of that, since 'b' points to an array, I believe that '*b -
1' is out of bounds. I think the cast could discard "the actual" bounds
and establish new ones; possibly interpreted by the implementation as an
instruction to forget what it knew.

- Shao Miller
 
B

Ben Bacarisse

Philip Lantz said:
fir said:
Also - I think if try to use some way of optimization
where instead of checking some edge values like

if(x>=0 && x<500 && y>=0 && y<500)
tab[y][x] = 1;

alloc some edge ram and do not bother about x=-1 or x=tab_max_x+1

but here it would be convenient to cast some pointer to type
tab[500][500] 'into' wider_tab[502][502] in such way that
tab[0][0] would correspond to wider_tab[1][1] (and tab[-1][-1]
to wider_tab[0][0])

int wider_tab[501*501+1];
int (*tab)[500] = (int (*)[500])&wider_tab[500+1];

tab[0][0] is wider_tab[501]
tab[1][0] is wider_tab[1001]
tab[500][500] is wider_tab[501*501]
tab[-1][-1] is wider_tab[0]

I think the OP wants an 'dead' edge all the way round. I.e. I think
they want:

int wider_tab[(N+2)*(N+2)];
int (*tab)[N+2] = (int (*)[N+2])&wider_tab[N+2+1];

(for N=500). You could also (probably) get away with using plain 2D
arrays for a little more clarity:

int wider_tab[N+2][N+2];
int (*tab)[N+2] = (void *)&wider_tab[1][1];

For illustration, when N=5, the output of

memset(wider_tab, -1, sizeof wider_tab); // ok, know...
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
tab[j] = i*10 + j;
for (int i = 0; i < N+2; i++, putchar('\n'))
for (int j = 0; j < N+2; j++)
printf("%3d", wider_tab[j]);

would be:

-1 -1 -1 -1 -1 -1 -1
-1 0 1 2 3 4 -1
-1 10 11 12 13 14 -1
-1 20 21 22 23 24 -1
-1 30 31 32 33 34 -1
-1 40 41 42 43 44 -1
-1 -1 -1 -1 -1 -1 -1

<snip warnings>
 
F

fir

W dniu czwartek, 20 grudnia 2012 14:38:45 UTC+1 użytkownik Ben Bacarisse napisał:
fir wrote:
Also - I think if try to use some way of optimization
where instead of checking some edge values like

if(x>=0 && x<500 && y>=0 && y<500)
tab[y][x] = 1;

alloc some edge ram and do not bother about x=-1 or x=tab_max_x+1

but here it would be convenient to cast some pointer to type
tab[500][500] 'into' wider_tab[502][502] in such way that
tab[0][0] would correspond to wider_tab[1][1] (and tab[-1][-1]
to wider_tab[0][0])
int wider_tab[501*501+1];
int (*tab)[500] = (int (*)[500])&wider_tab[500+1];
tab[0][0] is wider_tab[501]
tab[1][0] is wider_tab[1001]
tab[500][500] is wider_tab[501*501]
tab[-1][-1] is wider_tab[0]



I think the OP wants an 'dead' edge all the way round. I.e. I think

they want:



int wider_tab[(N+2)*(N+2)];

int (*tab)[N+2] = (int (*)[N+2])&wider_tab[N+2+1];



(for N=500). You could also (probably) get away with using plain 2D

arrays for a little more clarity:



int wider_tab[N+2][N+2];
int (*tab)[N+2] = (void *)&wider_tab[1][1];

that is exactly what i want, but here above is it vector of pointers or lite/solid block of addresable ram (with no other area pointers?),
(somewhat sad to say but i forgot of was atways somewhat out to array pointer subtlities :/ like this)
what way "int (*tab)[N+2]" should be read?

For illustration, when N=5, the output of



memset(wider_tab, -1, sizeof wider_tab); // ok, know...

for (int i = 0; i < N; i++)

for (int j = 0; j < N; j++)

tab[j] = i*10 + j;

for (int i = 0; i < N+2; i++, putchar('\n'))

for (int j = 0; j < N+2; j++)

printf("%3d", wider_tab[j]);



would be:



-1 -1 -1 -1 -1 -1 -1

-1 0 1 2 3 4 -1

-1 10 11 12 13 14 -1

-1 20 21 22 23 24 -1

-1 30 31 32 33 34 -1

-1 40 41 42 43 44 -1

-1 -1 -1 -1 -1 -1 -1



<snip warnings>
 
T

Tim Rentsch

fir said:
Can I use c arrays in such way tab[-1] or tab[-1][-1] (I mean when index is below zero)?

Also - I think if try to use some way of optimization
where instead of checking some edge values like

if(x>=0 && x<500 && y>=0 && y<500)
tab[y][x] = 1;

alloc some edge ram and do not bother about x=-1 or x=tab_max_x+1

but here it would be convenient to cast some pointer ot type tab[500][500] 'into' wider_tab[502][502]
in such way that tab[0][0] wolul correspond to wider_tab[1][1] (and tab[-1][-1] to wider_tab[0][0])

Can I get something like that? (If not I am sad)

The short answer is no. If E is any expression of array type,
any use of (E)[-1] or even just ((E)-1) is undefined behavior.

To get something like what you want, you would have to use
an array of pointers, those pointers being of type (int *),
and the type of 'tab' being (int **), with tab pointing at
the second element of the array (ie, at index [1]). The
pointers in the pointer array should point into a large
one-dimensional array, eg, 'int tab_space[ 502 * 502 ];'.
 
F

fir

W dniu czwartek, 20 grudnia 2012 18:12:44 UTC+1 użytkownik Tim Rentschnapisał:
Can I use c arrays in such way tab[-1] or tab[-1][-1] (I mean when index is below zero)?
Also - I think if try to use some way of optimization
where instead of checking some edge values like

if(x>=0 && x<500 && y>=0 && y<500)
tab[y][x] = 1;
alloc some edge ram and do not bother about x=-1 or x=tab_max_x+1
but here it would be convenient to cast some pointer ot type tab[500][500] 'into' wider_tab[502][502]
in such way that tab[0][0] wolul correspond to wider_tab[1][1] (and tab[-1][-1] to wider_tab[0][0])
Can I get something like that? (If not I am sad)



The short answer is no. If E is any expression of array type,

any use of (E)[-1] or even just ((E)-1) is undefined behavior.



To get something like what you want, you would have to use

an array of pointers, those pointers being of type (int *),

and the type of 'tab' being (int **), with tab pointing at

the second element of the array (ie, at index [1]). The

pointers in the pointer array should point into a large

one-dimensional array, eg, 'int tab_space[ 502 * 502 ];'.

what with

int (*tab)[N+2] = (void *)&wider_tab[1][1];

isnt tab here a pointer to "int somechunk[502]" ?

and if so, tab+1 (or tab[1]) woluld be next one "int some[502}" laying after previous -

so if it is working -> (tab[j]) (or tab[j]), it should be working theway I would exactly like- so it would be grrt (great I mean)

as to -1 as far as i remember ritche wrote
(in c development historical note) that this
square bracket syntax is only a sugar/alias
to pointers *(a+5) becomes a[5] here (or even
5[a] points the same as denoted in wiki - so it is maybe just mechanical trick), so
by analogy if *(a-1) works a[-1] should be working also
 
S

Shao Miller

W dniu czwartek, 20 grudnia 2012 18:12:44 UTC+1 użytkownik Tim Rentsch napisał:
The short answer is no. If E is any expression of array type,
any use of (E)[-1] or even just ((E)-1) is undefined behavior.

as to -1 as far as i remember ritche wrote
(in c development historical note) that this
square bracket syntax is only a sugar/alias
to pointers *(a+5) becomes a[5] here (or even
5[a] points the same as denoted in wiki - so it is maybe just mechanical trick), so
by analogy if *(a-1) works a[-1] should be working also

It is important to carefully note what Tim said about the type of 'E'.
If 'E' is a _pointer_, that's different than if 'E' is an _array_ which
happens to yield a pointer value in some contexts.

If 'E' is an array, the pointer value it yields (when it's not the
immediate operand of unary '&' or 'sizeof') is pointing to the lower
bound for the array. Subtracting 1 from that pointer value is thus
undefined behaviour, even if there so happens to be an object with
suitable type (or any type) available immediately before the array.

- Shao Miller
 
S

Shao Miller

It is important to carefully note what Tim said about the type of 'E'.

Apologies. I meant Mr. T. Rentsch.
If 'E' is an array, the pointer value it yields (when it's not the
immediate operand of unary '&' or 'sizeof') [...]

Apologies. I forgot C11's '_Alignof', too.

- Shao Miller
 
P

Philip Lantz

Robert said:
fir said:
Can I use c arrays in such way tab[-1] or tab[-1][-1] (I mean when
index is below zero)?

Also - I think if try to use some way of optimization
where instead of checking some edge values like

if(x>=0 && x<500 && y>=0 && y<500)
tab[y][x] = 1;

alloc some edge ram and do not bother about x=-1 or x=tab_max_x+1

but here it would be convenient to cast some pointer to type
tab[500][500] 'into' wider_tab[502][502] in such way that
tab[0][0] would correspond to wider_tab[1][1] (and tab[-1][-1]
to wider_tab[0][0])


I think you can do something like this:

int a[12][12];

void f()
{
int (*b)[10][12]; // note: use only 0..9 in second index

b = (int (*)[10][12])&(a[1][1]);

(*b)[2][2] = 3;
}

Given that the array layout is standardized, I *think* that doesn't
violate any rules. You'd have a row and column of "pad" around the
10x10 array.

If you don't need to be able to use a negative index in the second
dimension, you can do this without a cast, and the behavior is
definitely guaranteed:

int a[12][12];
int (*b)[12] = &a[1];

b[-1][0] is a[0][0]
b[0][0] is a[1][0]

I'm less confident that using a -1 as an index is guaranteed to work,
but I think it might be.

Using -1 as an index in a one-dimensional array is guaranteed to work:

int a[12];
int *b = &a[1];
b[-1] /* This is guaranteed to access a[0]. */

With a multi-dimensional array, it is less clear that the behavior is
guaranteed when using -1 as an index for anything other than the last
dimension, but I think it is, and even if it is not guaranteed by the
standard, I believe it is guaranteed by all implementations.
 
T

Tim Rentsch

fir said:
[citation for Tim Rentsch]
Can I use c arrays in such way tab[-1] or tab[-1][-1] (I mean when index is below zero)?
Also - I think if try to use some way of optimization
where instead of checking some edge values like

if(x>=0 && x<500 && y>=0 && y<500)
tab[y][x] = 1;
alloc some edge ram and do not bother about x=-1 or x=tab_max_x+1
but here it would be convenient to cast some pointer ot type tab[500][500] 'into' wider_tab[502][502]
in such way that tab[0][0] wolul correspond to wider_tab[1][1] (and tab[-1][-1] to wider_tab[0][0])
Can I get something like that? (If not I am sad)



The short answer is no. If E is any expression of array type,

any use of (E)[-1] or even just ((E)-1) is undefined behavior.



To get something like what you want, you would have to use

an array of pointers, those pointers being of type (int *),

and the type of 'tab' being (int **), with tab pointing at

the second element of the array (ie, at index [1]). The

pointers in the pointer array should point into a large

one-dimensional array, eg, 'int tab_space[ 502 * 502 ];'.

Dear Professor:

Please change your settings, or edit your postings, or both, to
get rid of extraneous blank lines.
what with

int (*tab)[N+2] = (void *)&wider_tab[1][1];

isnt tab here a pointer to "int somechunk[502]" ?

and if so, tab+1 (or tab[1]) woluld be next one "int some[502}" laying
after previous -

so if it is working -> (tab[j]) (or tab[j]), it should be
working the way I would exactly like- so it would be grrt (great I
mean)


Indexing in C is not defined just in terms of address
calculation. Address calculation is one aspect, but there
are additional constraints, and those constraints must be
observed; otherwise ALL BETS ARE OFF. The approach
described above violates those constraints. ANY approach
using pointer to array types, that attempts to index an
expression of array type with an index value of -1, will
violate the constraints. There is NO WAY to do what you
want to do using regular arrays or pointers to arrays; use
an array of pointers, and use type (int **) for the
accessing identifer ('tab' in the above) instead.
as to -1 as far as i remember ritche wrote (in c development
historical note) that this square bracket syntax is only a
sugar/alias to pointers *(a+5) becomes a[5] here (or even 5[a]
points the same as denoted in wiki - so it is maybe just
mechanical trick), so by analogy if *(a-1) works a[-1] should be
working also

C is now defined by the ISO document on it. Any writing by
Ritchie, however much we might enjoy or appreciate it, is no
longer authoritative.
 
T

Tim Rentsch

Philip Lantz said:
Robert said:
fir said:
Can I use c arrays in such way tab[-1] or tab[-1][-1] (I mean when
index is below zero)?

Also - I think if try to use some way of optimization
where instead of checking some edge values like

if(x>=0 && x<500 && y>=0 && y<500)
tab[y][x] = 1;

alloc some edge ram and do not bother about x=-1 or x=tab_max_x+1

but here it would be convenient to cast some pointer to type
tab[500][500] 'into' wider_tab[502][502] in such way that
tab[0][0] would correspond to wider_tab[1][1] (and tab[-1][-1]
to wider_tab[0][0])


I think you can do something like this:

int a[12][12];

void f()
{
int (*b)[10][12]; // note: use only 0..9 in second index

b = (int (*)[10][12])&(a[1][1]);

(*b)[2][2] = 3;
}

Given that the array layout is standardized, I *think* that doesn't
violate any rules. You'd have a row and column of "pad" around the
10x10 array.

If you don't need to be able to use a negative index in the second
dimension, you can do this without a cast, and the behavior is
definitely guaranteed:

int a[12][12];
int (*b)[12] = &a[1];

b[-1][0] is a[0][0]
b[0][0] is a[1][0]

Only because the expression being indexed with -1 is of pointer
type rather than array type.
I'm less confident that using a -1 as an index is guaranteed to work,
but I think it might be.

Using -1 as an index in a one-dimensional array is guaranteed to work:

int a[12];
int *b = &a[1];
b[-1] /* This is guaranteed to access a[0]. */

Again, only because the expression being indexed with -1 is of
pointer type rather than array type. If b were declared as

int (*b)[11] = (void*)&a[1];

then trying to access (*b)[-1] is undefined behavior.

With a multi-dimensional array, it is less clear that the behavior is
guaranteed when using -1 as an index for anything other than the last
dimension,

Presumably you meant for anything other than the first dimension.
but I think it is,

Any access through an array type must have an index value within
the bounds of the type of the array. An index value of -1 never
qualifies.
and even if it is not guaranteed by the standard, I believe it
is guaranteed by all implementations.

What I think you mean is that all implementations do in fact
produce (at the present time) the desired behavior. Even if
that's true, I expect no implementation actually guarantees it,
and certainly not all of them do.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,130
Latest member
MitchellTe
Top