buda <kulghan@hotmai l.com> wrote:[color=blue]
> Hello,
> Is the behaviour of indexing an array with a negative number (like a[-1])
> defined by the standard?[/color]
Not 101% certain, but a[n] should point to *(a+(sizeof(*a) *n)), so it should
be *(a+(sizeof(a)*-1)), that is 1 memory-spot before a starts.
"buda" <kulghan@hotmai l.com> writes:
[color=blue]
> Is the behaviour of indexing an array with a negative number (like
> a[-1]) defined by the standard?[/color]
If the expression refers to an existing array element, then yes.
Otherwise, the behavior is undefined.
For example, given the code
int b [3];
int *a = b + 1;
the expression `a [-1]' is valid and refers to the same object as
`b [0]'.
Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Viktor Lofgren <root@eudial.no s--pam.mine.nu> writes:
[color=blue]
> buda <kulghan@hotmai l.com> wrote:[color=green]
>> Hello,
>> Is the behaviour of indexing an array with a negative number (like
>> a[-1]) defined by the standard?[/color]
>
> Not 101% certain, but a[n] should point to *(a+(sizeof(*a) *n)),[/color]
Your statement is misleading. First of all, `a [n]' is not necessarily
a pointer, so it's not necessarily pointing to anything. You probably
mean "the address of `a [n]' is the same as ...".
More importantly, the address of `a [n]' is the same as the address of
`*(a + n)', which is different from `*(a + (sizeof (*a) * n))' unless
`sizeof *a' happens to be 1. However the address of `a [n]' is the same
as the address of `*((char *)a + (sizeof (*a) * n))', i.e. the addresses
of `a' and `a [n]' differ by `sizeof (*a) * n' bytes.
Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Martin Dickopp <expires-2004-06-30@zero-based.org> wrote:[color=blue]
> More importantly, the address of `a [n]' is the same as the address of
> `*(a + n)', which is different from `*(a + (sizeof (*a) * n))' unless
> `sizeof *a' happens to be 1. However the address of `a [n]' is the same
> as the address of `*((char *)a + (sizeof (*a) * n))', i.e. the addresses
> of `a' and `a [n]' differ by `sizeof (*a) * n' bytes.[/color]
No, if a is int_32*, a[n] = *(a + 4 * n).
For an example:
int* b = NULL;
printf("%d %d", &b[0], &b[1]);
prints "0 4" when executed, if a[n] would be *(a+n), it would print "0 1".
In article <2wRrc.85$dx3.1 112@newsb.telia .net>,
Viktor Lofgren <root@eudial.no s--pam.mine.nu> wrote:
[color=blue]
> Martin Dickopp <expires-2004-06-30@zero-based.org> wrote:[color=green]
> > More importantly, the address of `a [n]' is the same as the address of
> > `*(a + n)', which is different from `*(a + (sizeof (*a) * n))' unless
> > `sizeof *a' happens to be 1. However the address of `a [n]' is the same
> > as the address of `*((char *)a + (sizeof (*a) * n))', i.e. the addresses
> > of `a' and `a [n]' differ by `sizeof (*a) * n' bytes.[/color]
>
> No, if a is int_32*, a[n] = *(a + 4 * n).
> For an example:
>
> int* b = NULL;
> printf("%d %d", &b[0], &b[1]);
>
> prints "0 4" when executed, if a[n] would be *(a+n), it would print "0 1".[/color]
I suggest you try
int a [10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int n = 1;
Viktor Lofgren <root@eudial.no s--pam.mine.nu> writes:
[color=blue]
> Martin Dickopp <expires-2004-06-30@zero-based.org> wrote:[color=green]
>> More importantly, the address of `a [n]' is the same as the address of
>> `*(a + n)', which is different from `*(a + (sizeof (*a) * n))' unless
>> `sizeof *a' happens to be 1. However the address of `a [n]' is the same
>> as the address of `*((char *)a + (sizeof (*a) * n))', i.e. the addresses
>> of `a' and `a [n]' differ by `sizeof (*a) * n' bytes.[/color]
>
> No, if a is int_32*, a[n] = *(a + 4 * n).[/color]
No. Please look up in your C book what the effect of the `+' operator
is if one operand is a pointer and the other is an integer.
[color=blue]
> For an example:
>
> int* b = NULL;
> printf("%d %d", &b[0], &b[1]);
>
> prints "0 4" when executed, if a[n] would be *(a+n), it would print "0 1".[/color]
This code fragment invokes undefined behavior for two reasons: First of
all, the "%d" specifier expects an `int' argument, but `&b[0]' and
`&b[1]' have type `int *'. Secondly, it is undefined behavior to add
something to a null pointer, as is done in the expression `&b[1]'.
Since the code invokes undefined behavior, anything could have happened,
including printing "0 4", printing "0 1", or printing a Shakespearean
sonnet.
If you really want a program that demonstrates that you're wrong, try
this one:
#include <stdio.h>
int main (void)
{
int a [4];
printf ("address of a [1] is %p\n", (void *)&a [1]);
printf ("address of *(a + 1) is %p\n", (void *)&*(a + 1));
printf ("address of *(a + 4 * 1) is %p\n", (void *)&*(a + 4 * 1));
return 0;
}
Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
>> More importantly, the address of `a [n]' is the same as the address of[color=blue][color=green]
>> `*(a + n)', which is different from `*(a + (sizeof (*a) * n))' unless
>> `sizeof *a' happens to be 1. However the address of `a [n]' is the same
>> as the address of `*((char *)a + (sizeof (*a) * n))', i.e. the addresses
>> of `a' and `a [n]' differ by `sizeof (*a) * n' bytes.[/color]
>
>No, if a is int_32*, a[n] = *(a + 4 * n).[/color]
No. I think you mean a[n] = *(a addl (4 mull n))
where addl and mull are assembly-language arithmetic operators.
[color=blue]
>For an example:
>
> int* b = NULL;
> printf("%d %d", &b[0], &b[1]);
>
>prints "0 4" when executed, if a[n] would be *(a+n), it would print "0 1".[/color]
C operators are different from assembly-language ones, especially
when pointers are involved.
Also, there is no guarantee that sizeof(a 32-bit integer type) does not
equal 1.
Allin Cottrell wrote:[color=blue]
>
> buda wrote:[color=green]
> > Hello,
> > Is the behaviour of indexing an array with a negative number (like a[-1])
> > defined by the standard?[/color]
>
> It's undefined behaviour. See section 6.5.6 of the 1999 C standard.
>
> Allin Cottrell[/color]
Maybe you could give us a wee bit more to go on...
Since we might be looking at two different documents,
are you refering to the section titled -
"6.5.6 Additive operators"?
I'm not sure how the following is "undefined behaviour"...
On Sat, 22 May 2004, Stephen L. wrote:[color=blue]
>
> Allin Cottrell wrote:[color=green]
> > buda wrote:[color=darkred]
> > > Is the behaviour of indexing an array with a negative number (like a[-1])
> > > defined by the standard?[/color]
> >
> > It's undefined behaviour. See section 6.5.6 of the 1999 C standard.[/color]
>
> I'm not sure how the following is "undefined behaviour"...[/color]
It's not. However, if 'a' is, as the OP said, an array name, then
indeed indexing 'a' with a negative subscript will dereference a pointer
that's not pointing to an object. E.g.,
foo a[bar]; a[-1];
is *always*, without exception, undefined behavior.
Doing the same thing with a pointer, e.g.
baz *p = quux; p[-1];
may or may not invoke UB, depending on the value of 'quux'. In your
example, there is no undefined behavior.
-Arthur
[color=blue]
> #include <stdio.h>
>
> int
> main()
> {
> char str[] = "1234567890 ";
> char *p = &str[ sizeof (str) - 1 ]; /* `p' points to string's
> NULL */
>
>
> printf("Charact er should be '0', '%c'.\n", p[ -1 ]);
> printf("Charact er should be '9', '%c'.\n", p[ -2 ]);
>
> printf("Charact er should be '0', '%c'\n", *(p - 1));
> printf("Charact er should be '9', '%c'\n", *(p - 2));
>
> printf("Same as above, '0', '%c'.\n", *--p); /* Is _this_ undefined
> too? */
> printf("Same as above, '9', '%c'.\n", *--p);
>
> return (0);
> }[/color]
In article <news:2wRrc.85$ dx3.1112@newsb. telia.net>
Viktor Lofgren <root@eudial.no s--pam.mine.nu> writes:[color=blue]
>For an example:
>
> int* b = NULL;
> printf("%d %d", &b[0], &b[1]);
>
>prints "0 4" when executed, if a[n] would be *(a+n), it would print "0 1".[/color]
I ran this on a Data General Eclipse[%] and it printed:
1879048192 1879048194
Can you explain this?
(Convert the above to hex for a big hint. The numbers are 0x70000000
and 0x70000002 respectively. The facts that sizeof(int) is 4 and
that "int *" uses "word pointers", with 16-bit words, are both
important.)
[% Actually I do not have access to one, but this is what it might
print, if I remember right. I made up a segment-and-ring number
of 0x7 and am not sure that this is correct for user-mode code, or
even the right number of bits.]
--
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.
"buda" <kulghan@hotmai l.com> writes:[color=blue]
> Hello,
> Is the behaviour of indexing an array with a negative number (like a[-1])
> defined by the standard?[/color]
If a is an array object, then evaluating a[-1] invokes undefined
behavior.
Array indexing is really a binary operation ("binary" meaning it takes
two operands); the left operand is a pointer to some object type, and
the right operand is an integer (or vice versa; see below). x[y] is
equivalent to *(x+y). Since x is a pointer and y is an integer, the
"+" performs pointer arithmetic.
If "a" points into the middle of an array object, "a[-1]" yields the
value of the array element just before the one that "a" points to.
It may seem odd that the left operand is expected to be a pointer, not
an array. It works for arrays because, in most expression contexts,
an array name is converted to a pointer to its first element.
(x[y] is equivalent to *(x+y). Since addition is commutative, *(x+y)
is equivalent to *(y+x), which is equivalent to y[x]. Thus
5["abcdef"] is a legal expression, equal to 'f'. This is interesting,
but not particularly useful.)
See section 6 of the C FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
for more information. While you're there, read the whole thing.
--
Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
buda wrote:[color=blue]
>
> Hello,
> Is the behaviour of indexing an array with a negative number (like a[-1])
> defined by the standard?
>[/color]
You can do something like the following;
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *a, *b;
b = malloc(21 * sizeof int);
a = b + 11;
a[5] = 42;
a[-5] = 24;
printf("The values are %d and %d\n",a[5],a[-5]);
}
This technique can be useful when converting a Pascal program
that is using negative subscripts.
--
+----------------------------------------------------------------+
| Charles and Francis Richmond richmond at plano dot net |
+----------------------------------------------------------------+
Comment