Hello,
Is the behaviour of indexing an array with a negative number (like a[-1])
defined by the standard? 19 7731
buda <ku*****@hotmail.com> wrote: Hello, Is the behaviour of indexing an array with a negative number (like a[-1]) defined by the standard?
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" <ku*****@hotmail.com> writes: Is the behaviour of indexing an array with a negative number (like a[-1]) defined by the standard?
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. \_/
buda wrote: Hello, Is the behaviour of indexing an array with a negative number (like a[-1]) defined by the standard?
It's undefined behaviour. See section 6.5.6 of the 1999 C standard.
Allin Cottrell
Viktor Lofgren <ro**@eudial.nos--pam.mine.nu> writes: buda <ku*****@hotmail.com> wrote: Hello, Is the behaviour of indexing an array with a negative number (like a[-1]) defined by the standard?
Not 101% certain, but a[n] should point to *(a+(sizeof(*a)*n)),
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 <ex****************@zero-based.org> wrote: 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.
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 <2w***************@newsb.telia.net>,
Viktor Lofgren <ro**@eudial.nos--pam.mine.nu> wrote: Martin Dickopp <ex****************@zero-based.org> wrote: 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.
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".
I suggest you try
int a [10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int n = 1;
printf ("%d %d\n", a [n], * (a + 4 * n));
and tell us what happens.
Viktor Lofgren <ro**@eudial.nos--pam.mine.nu> writes: Martin Dickopp <ex****************@zero-based.org> wrote: 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. No, if a is int_32*, a[n] = *(a + 4 * n).
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.
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".
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 `*(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. No, if a is int_32*, a[n] = *(a + 4 * n).
No. I think you mean a[n] = *(a addl (4 mull n))
where addl and mull are assembly-language arithmetic operators.
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".
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.
Gordon L. Burditt
Allin Cottrell wrote: buda wrote: Hello, Is the behaviour of indexing an array with a negative number (like a[-1]) defined by the standard?
It's undefined behaviour. See section 6.5.6 of the 1999 C standard.
Allin Cottrell
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"...
/********************************************/
#include <stdio.h>
int
main()
{
char str[] = "1234567890";
char *p = &str[ sizeof (str) - 1 ]; /* `p' points to string's
NULL */
printf("Character should be '0', '%c'.\n", p[ -1 ]);
printf("Character should be '9', '%c'.\n", p[ -2 ]);
printf("Character should be '0', '%c'\n", *(p - 1));
printf("Character 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);
}
--
Stephen
On Sat, 22 May 2004, Stephen L. wrote: Allin Cottrell wrote: buda wrote: Is the behaviour of indexing an array with a negative number (like a[-1]) defined by the standard? It's undefined behaviour. See section 6.5.6 of the 1999 C standard.
I'm not sure how the following is "undefined behaviour"...
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
#include <stdio.h>
int main() { char str[] = "1234567890"; char *p = &str[ sizeof (str) - 1 ]; /* `p' points to string's NULL */
printf("Character should be '0', '%c'.\n", p[ -1 ]); printf("Character should be '9', '%c'.\n", p[ -2 ]);
printf("Character should be '0', '%c'\n", *(p - 1)); printf("Character 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); }
"Stephen L." <sd*********@cast-com.net> writes: char str[] = "1234567890"; char *p = &str[ sizeof (str) - 1 ]; /* `p' points to string's NULL */
ITYM null character instead of NULL. (NULL is a macro which expands to
a null /pointer/ constant.)
Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
In article <news:2w***************@newsb.telia.net>
Viktor Lofgren <ro**@eudial.nos--pam.mine.nu> writes: 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".
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" <ku*****@hotmail.com> writes: Hello, Is the behaviour of indexing an array with a negative number (like a[-1]) defined by the standard?
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_Keith) ks***@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: Hello, Is the behaviour of indexing an array with a negative number (like a[-1]) defined by the standard?
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 |
+----------------------------------------------------------------+
In <c8********@news3.newsguy.com> Chris Torek <no****@torek.net> writes: I ran this on a Data General Eclipse[%] and it printed:
<snip>
[% Actually I do not have access to one, but this is what it might print, if I remember right.
Did anyone implement standard C on it? How about K&R C?
Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
>In <c8********@news3.newsguy.com> Chris Torek <no****@torek.net> writes: I ran this on a Data General Eclipse[%] ... [% Actually I do not have access to one, but this is what it might print, if I remember right.
In article <news:c8***********@sunnews.cern.ch>
Dan Pop <Da*****@cern.ch> asked:Did anyone implement standard C on it? How about K&R C?
I am not at all sure about Standard C. The machine I used ran
a (somewhat bizarre and twisted variation on) 4.2BSD Unix. The
C compiler implemented everything required to compile typical
Unix programs. I think that covers "K&R C" and then some -- the
compiler had enumerations and "unsigned char", for instance.
Quite a lot of our C code had to be fixed up not to make assumptions
about pointer formats.
Besides the pointer trickiness, the main thing I remember about
the Eclipse is that the output from perror() was broken. It printed
a two digit error number, followed by no whitespace, followed by
the string, so that one would get things like:
prog: cannot open foo.dat: 02No such file or directory
(I also remember something about bogus newlines, perhaps before the
"02".)
(This machine and the Pyramid were responsible for our group at
the University of Maryland making numerous fixes to varous programs.
The Pyramid found non-pointer bugs. For instance, MH used the
interesting calling sequence "parameter passing by register
assumption"[%], which was impossible on the Pyramid due to its
register windows. The Pyramid also exposed all the programs that
failed to "return 0" or "exit(0)" from main. Return values from
functions had to be stored in register "pr0" in the register-window
assigned to that function, and calling some other function did not
affect one's own pr0, only one's tr0. Hence, programs that on the
VAX returned whatever was left in r0 -- which was the return value
from the most-recently-called function -- instead returned their
first argument. For main(), this was the parameter argc.)
[% An illustration, not necessarily the actual MH code and using
ANSI C syntax rather than Classic C:
void f1(struct S *param) {
register int a, b;
register FILE *some_file;
...
some_file = fopen("some_path", "w");
f2(param, a);
...
}
void f2(register struct S *param, register int a) {
register FILE *fp; /* NOTE: NOT INITIALIZED! */
...
fprintf(fp, "%s: %d\n", param->zig, a);
...
}
This worked on the VAX, and even the PDP-11, because the machine's
registers were handed out in a fixed, known order. On the VAX,
"some_file" wound up in r9; on the PDP-11 it was in r3. In each
case, declaring "fp" third in f2() caused the C compiler to reserve
the same register -- which still held the opened FILE *! The VAX
C compiler gave you six registers, while the PDP-11 gave you only
three, so the actual "parameter passing by register assumption" in
MH was definitely in the first six "register" variables, and almost
certainly in the first three.]
--
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.
C will allow you to use a negative index. The index into an array is
signed integer. I guess you can use negative indices if you make sure
that the memory before the start of the array is allocated for this.
I remember seeing use of negative in Tanenbaum's MINIX book. The
positive indices were used as user task pids and negative indices
were used for MINIX tasks.
Sandeep
-- http://www.EventHelix.com/EventStudio
EventStudio 2.0 - Generate Sequence Diagrams and Use Case Diagrams in PDF
EventHelix.com wrote: ... The index into an array is signed integer. I guess you can use negative indices if you make sure that the memory before the start of the array is allocated for this.
Doing this little trick is not C. A resource other than the
the ISO/IEC Internation Standard may suggest this and your compiler may
accept it in a way you expect. But that does not make it C. The C
Language describes this as undefined behavior.
The Standard specifically describes many circumstances of
undefined behavor. The following circumstance seems to make operation
clearly UB.
— Addition or subtraction of a pointer into, or just beyond,
an array object and an integer type produces a result that
does not point into, or just beyond, the same array object (6.5.6).
--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email) http://www.geocities.com/abowers822/ ev********@hotmail.com (EventHelix.com) writes: C will allow you to use a negative index. The index into an array is signed integer. I guess you can use negative indices if you make sure that the memory before the start of the array is allocated for this.
I remember seeing use of negative in Tanenbaum's MINIX book. The positive indices were used as user task pids and negative indices were used for MINIX tasks.
I'll bet that the "array" being indexed with a negative integer was
actually a pointer into the middle of an array object.
--
Keith Thompson (The_Other_Keith) ks***@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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Scott Kelley |
last post by:
Is there a way to reset all elements of an array with a single instruction?
I want to set all elements to zero. Currently looping to do so.
thx,
Scott Kelley
|
by: Eric Smith |
last post by:
Is a structure containing an incomplete array as its last element (per
paragraph 2 of section 6.7.2.1 of ISO/IEC 9899:1999 (E)) itself an
incomplete type? That appears to be indicated by paragraph...
|
by: Amarendra |
last post by:
Folks,
This structure padding issue is bothering me now, could
not locate a satisfactory answer on clc, so here it goes...
I have a structure, given below:
typedef struct {
int flag;
char...
|
by: buda |
last post by:
Hi,
I've been wondering for a while now (and always forgot to ask :) what is the
exact quote from the Standard that forbids the use of (&array)
(when x >= number_of_columns) as stated in the FAQ...
|
by: Eric Laberge |
last post by:
Aloha!
I've been reading the standard (May '05 draft, actually) and stumbled across
this:
6.7.1 Initialization
§20 "If the aggregate or union contains elements or members that are
aggregates...
|
by: Lalatendu Das |
last post by:
hi let's say i have a structure
struct test {
int A;
char B;
int C;
};
this above structure defination always going to take 16 byte in
memeory in whatever manner we align the member variables...
|
by: Kavya |
last post by:
int main (){
int a={{1,2,3},{4,5,6}};
int (*ptr)=a;
/* This should be fine and give 3 as output*/
printf("%d\n",(*ptr));
++ptr;
|
by: Francois Grieu |
last post by:
Hello, I'm asking myself all kind of questions on allocating
an array of struct with proper alignment.
Is the following code oorrect ?
I'm most interested by the statement
t =...
|
by: aarklon |
last post by:
Hi all,
arrays are guaranteed to be contiguous with no padding before or
after any array member , but what about enums ..???
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
| |