jack@citcom.UUCP (Jack Waugh) (11/30/87)
It recently occurred to me that there is no syntax to take the address of an array, although an expression of that type can be derived from an array of arrays, and a variable of that type can be declared. The obvious syntax, &a, is incorrect because you can only & an lvalue. [Neophytes, please don't tell the world the name of an array denotes its address. It denotes the address of the first element, which does not mean the same thing if you add an integer to it.]
gwyn@brl-smoke.ARPA (Doug Gwyn ) (11/30/87)
In article <126@citcom.UUCP> jack@citcom.UUCP (Jack Waugh) writes: >It recently occurred to me that there is no syntax to take the >address of an array... Arrays are not first-class citizens in C. Nevertheless, the proposed ANSI standard for C permits &array.
decot@hpisod2.HP.COM (Dave Decot) (11/30/87)
> It recently occurred to me that there is no syntax to take the > address of an array, although an expression of that type can be > derived from an array of arrays, and a variable of that type > can be declared. The obvious syntax, &a, is incorrect because > you can only & an lvalue. > > [Neophytes, please don't tell the world the name of an array denotes > its address. It denotes the address of the first element, which > does not mean the same thing if you add an integer to it.] I screamed in horror when I read in K&R of this design botch. This is the fundamental reason you can now take any type (including a structure containing an array!!) and assign to it, pass it to and return it from functions, EXCEPT an array type. However, I propose the syntax "a[]" to refer to an lvalue which is the entire array a, and "&(a[])" (sorry, that's the precedence) to signify the address of the entire array a. In order to declare a formal parameter of an array type, one would have to supply the dimension in the brackets, since otherwise the size would be unknown: int (bubblesort(array, n))[MAX] int array[MAX], n; { int i, done, tmp, newarray[MAX]; newarray[] = array[]; /* copy the value of array to newarray */ /* gratuitous, yes, but this is an example */ do { done = 1; for (i = 0; i < n-1; i++) if (newarray[i] > newarray[i+1]) { tmp = newarray[i]; newarray[i] = newarray[i+1]; newarray[i+1] = tmp; done = 0; } } while (!done); return newarray[]; /* return the whole array */ } Dave Decot hpda!decot
throopw@xyzzy.UUCP (Wayne A. Throop) (12/02/87)
> jack@citcom.UUCP (Jack Waugh) > It recently occurred to me that there is no syntax to take the > address of an array, although an expression of that type can be > derived from an array of arrays, and a variable of that type > can be declared. The obvious syntax, &a, is incorrect because > you can only & an lvalue. Correct. This deficency is fixed in the draft ANSI standard for C, X3J11, by making objects of array type non-modifiable lvalues. See section 3.2.2.1 of the November 9th version of the draft standard for an explanation of what goes on for constructs such as (&array). -- "Suddenly I feel so... sapient." --- Fluffy -- Wayne Throop <the-known-world>!mcnc!rti!xyzzy!throopw
gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/02/87)
In article <2550034@hpisod2.HP.COM> decot@hpisod2.HP.COM (Dave Decot) writes: >However, I propose ... >In order to declare a formal parameter of an array type, one >would have to supply the dimension in the brackets, ... The X3J11 committee considered fixing the design of arrays in C to be full-fledged data object types, but soon realized that doing so would invalidate mountains of existing code. Feel free to fix it when you design la)) { never
pjh@mccc.UUCP (Peter J. Holsberg) (12/02/87)
OK - perhaps you had better tell us neophytes what you mean by the address of an array! -- Peter Holsberg UUCP: {rutgers!}princeton!mccc!pjh Technology Division CompuServe: 70240,334 Mercer College GEnie: PJHOLSBERG Trenton, NJ 08690 Voice: 1-609-586-4800
throopw@xyzzy.UUCP (Wayne A. Throop) (12/03/87)
> pjh@mccc.UUCP (Peter J. Holsberg) > OK - perhaps you had better tell us neophytes what you mean by the > address of an array! Same as address of anything else. It is an address which, when indirected, yields an array, and when "N" is added to it, yields the address of an array which is itself a member of an array "N" elements away from the array yielded by an indirection. A pointer to an integer array of 10 elements is declared by int (*a)[10]; and could be used like so a[N] /* Nth array of ten ints away from (*a) */ (*a)[N] /* Nth int in the array pointed to by a */ a[N][M] /* Mth int in the Nth array */ (*(a+N))[M] /* same as a[N][M] */ What could be simpler? -- Another interesting facet of ninja was the use of magic. They had a reputation as sorcerors and wizards who could fly and hypnotize, and walk through walls, and get away with huge deductions on their taxes. --- Bruce Israel martial-arts-request@brillig -- Wayne Throop <the-known-world>!mcnc!rti!xyzzy!throopw
karl@haddock.ISC.COM (Karl Heuer) (12/04/87)
In article <2550034@hpisod2.HP.COM> decot@hpisod2.HP.COM (Dave Decot) writes: >I propose the syntax "a[]" to refer to an lvalue which is the entire array a, Okay so far. >and "&(a[])" to signify the address of the entire array a. Unnecessary, since ANSI has blessed the simpler syntax "&a". >In order to declare a formal parameter of an array type, one would have to >supply the dimension in the brackets, since otherwise the size would be >unknown: > int (bubblesort(array, n))[MAX] int array[MAX], n; { ... } Nice try, but a formal argument declared "int array[MAX]" is already legal, and it means the wrong thing. (It's a backwards way of declaring a pointer. Cf. "char *argv[]", which really means "char **argv"; this is true even if you specify an explicit size.) As of the Oct86 Draft (and presumably the latest one, too), this was to be true even in prototype notation: void foo(int array[MAX]) { ... } doesn't do the "right thing" either. This is the first thing that needs to be changed; otherwise it will be nearly impossible to ever make arrays into first-class datatypes. The very first step, then, must be to ask ANSI to *forbid* array-typed formal arguments (as opposed to having them denote pointers). This would not break any existing code, because it would only affect prototypes, not old-style declarations. It's too late for me to have any influence on this decision, but if any of you have already submitted official proposals on this issue, you may still have a chance to stop ANSI from digging itself into this hole. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
sarima@gryphon.UUCP (12/05/87)
In article <163@mccc.UUCP> pjh@mccc.UUCP (Peter J. Holsberg) writes: > >OK - perhaps you had better tell us neophytes what you mean by the >address of an array! > Alright, I hope I can express this clearly. From the context in of the original article, the "address of an array" is a pointer to an "entire" array, rather than just to the first element of it. That is it is a pointer to an object of size sizeof(array) rather than an object of size sizeof(array[0]), thus adding one to such a pointer will result in a pointer to the next array object rather than the next element of the current array. To put this as a 'C' type declaration: a pointer to an array is of type: BASETYPE (*array_ptr)[ARRAYSIZE]; The most common way to get such a thing is to declare a two dimensional array and then write an expression like 'array[n]', with only one subscript. This evaluates to a pointer to the first sub-array of the two dimensional array. I hope I have not confused you too much with this rambling description:-)
ncbauers@ndsuvax.UUCP (Michael Bauers) (12/05/87)
In article <1854@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes: >In article <2550034@hpisod2.HP.COM> decot@hpisod2.HP.COM (Dave Decot) writes: >>I propose the syntax "a[]" to refer to an lvalue which is the entire array a, >Okay so far. >>and "&(a[])" to signify the address of the entire array a. >Unnecessary, since ANSI has blessed the simpler syntax "&a". Two questions. 1) I hate to sound picky but isn't &(a[]) the address of the array's When you say address of the entire array it sounds like you mean the address of the first element in the array. The convention as I understand it is to talk about it as you would in machine language. So isn't the original System V C complier standard also to refer to the address of the array's address &a. 2) When will the proposed ANSI standard be avaiable? When I interned for Northern Telecom, I was in a class on 'C' where the instructor mentioned this standard. It sounded like a good idea to me. In this standard will a structures address, or the entire structure be passed. I am not sure I like the fact that the entire structure is passed in our verion of C here. It seems that any thing more complex than a simple variable should have its address not its contents passed.
levy@ttrdc.UUCP (Daniel R. Levy) (12/08/87)
In article <532@ndsuvax.UUCP>, ncbauers@ndsuvax.UUCP (Michael Bauers) writes: >In article <1854@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes: >>In article <2550034@hpisod2.HP.COM> decot@hpisod2.HP.COM (Dave Decot) writes: >>>I propose the syntax "a[]" to refer to an lvalue which is the entire array a, >>Okay so far. >>>and "&(a[])" to signify the address of the entire array a. >>Unnecessary, since ANSI has blessed the simpler syntax "&a". > > 1) I hate to sound picky but isn't &(a[]) the address of the array's [first element?] -- drl > When you say address of the entire array it sounds like you mean > the address of the first element in the array. The convention as I > understand it is to talk about it as you would in machine language. > So isn't the original System V C complier standard also to refer > to the address of the array's address &a. (PLEASE guys, be easy on this fellow. Keep your fangs to yourself. Down boy! DOWWNN BOY!! [Grrrrrrrrr...]) In C, the usage of an "address" connotes more than mere location; the type of the address also connotes the size of the object being addressed. This size comes into play when the address is incremented or decremented by an integral value, or when the difference is taken between it and another address of the same type. The increment or decrement is taken to be in units of the type of object pointed to by the address. Likewise, the difference is taken to be in units of the type of object pointed to. The type of object addressed may of course be a aggregate data type such as an array or struct just as well as it could be a simple data type like int or char. -- |------------Dan Levy------------| Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa, | an Engihacker @ | <most AT&T machines>}!ttrdc!ttrda!levy | AT&T Computer Systems Division | Disclaimer? Huh? What disclaimer??? |--------Skokie, Illinois--------|
cl@dlhpedg.co.uk (Charles Lambert) (12/08/87)
In article <422@xyzzy.UUCP> throopw@xyzzy.UUCP (Wayne A. Throop) writes: >> pjh@mccc.UUCP (Peter J. Holsberg) >> OK - perhaps you had better tell us neophytes what you mean by the >> address of an array! > >Same as address of anything else. It is an address which, when >indirected, yields an array, and when "N" is added to it, yields the >address of an array which is itself a member of an array "N" elements >away from the array yielded by an indirection. > > [ several abstruse observations ] > >What could be simpler? Well, several other forms of explanation, I guess. This one confused me, and I *understand* the address of an array. (Just teasing) To put it another way.... Any object, of any type (integer, structure, array, etc.), has an address. Usually, if it is an object that occupies several words of memory, it is the address at which it begins. (Compiler theorists may be itching to tell me it might mean something else entirely; let's keep this simple.) The address of an object is the compiler's handle for manipulating it. You think of an object by its name; the compiler "thinks" of it by its address. The "address of an array" is the address that the compiler uses to access that array and to calculate the position of any element in the array. In C, the address of an array is the same as the address of its first element (array[0]). If you want to set up a pointer to the array, you get its address simply by naming it. Hence: pa = array; /* pa now contains the address of "array" */ which is exactly the same as pa = &array[0]; /* "&" means "address of", so pa contains the address of element [0] of "array" */ Now this is a slight quirk in C - the name of the array being a synonym for its address; for any other object (notably a struct) that is not true. If you want the address of a structure you must write ps = &mystruct; /* NOT ps = mystruct */ So we get back to the discussion from whence we came: why can't we be consistent and get the address of an array by pa = &array; ? To which the answer is: you can, with some compilers. [Further reading: The C Programming Language; Kernighan & Ritchie; pp.93-95] -------------------------- Charles Lambert
ncbauers@ndsuvax.UUCP (Michael Bauers) (12/10/87)
I must learn to write better, people keep telling me that with a pointer is associated a type. I know this...I program in C. What I was objecting to was when someone said 'address of array.' What they had meant to say I think was 'The adress of the array's pointer.' I was just noting that this was confusing. I was confused anyway. The article I was responding to was talking about taking the address of an array. The address of the array a[10] is just a. The address of the first element is also a (for single dimension arrays). The first element is *a. But the address of the array's pointer (what this person wanted to know) should be &a.
marty1@houdi.UUCP (M.BRILLIANT) (12/12/87)
In article <555@ndsuvax.UUCP>, ncbauers@ndsuvax.UUCP (Michael Bauers) writes: > The > address of the array a[10] is just a. The address of the first element > is also a (for single dimension arrays). The first element is *a. But > the address of the array's pointer ... should be &a. Huh? I tried writing a C program on UNIX(tm ATT) that referenced &a, and got the message "warning: & before array or function: ignored." That says there's no such thing as &a. M. B. Brilliant Marty AT&T-BL HO 3D-520 (201)-949-1858 Holmdel, NJ 07733 ihnp4!houdi!marty1
karl@haddock.ISC.COM (Karl Heuer) (12/12/87)
In article <555@ndsuvax.UUCP> ncbauers@ndsuvax.UUCP (Michael Bauers) writes: >But the address of the array's pointer (what this person wanted to know) >should be &a. Are you saying that "&a" should mean "&(&a[0])"? This doesn't make sense, as "&a[0]" is not an lvalue. The original question really was talking about the address of an entire array entity (which differs from the address of the first element in exactly the same way that the address of a structure differs from the address of its first member), and this is exactly the problem that X3J11 has fixed by legalizing "&a". Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) (12/12/87)
In article <1442@houdi.UUCP>, marty1@houdi.UUCP (M.BRILLIANT) writes: > > Huh? I tried writing a C program on UNIX(tm ATT) that referenced &a, > and got the message "warning: & before array or function: ignored." > That says there's no such thing as &a. > > M. B. Brilliant Marty This is like taking the address of a constant, say &0435241250, which of course is silly. I have been programming in C for 5 1/2 years and I've never needed to take the address of an array (except via &a[0], or just a). Why do programmers want to do this? Whats the point? Do other languages let you do this? What is the advantage? I can't see any. Please enlighten me. -- Larry Cipriani AT&T Network Systems at cbosgd!osu-cis!tut!lvc Ohio State University
c188-bl@katerina.uucp (Steven Brian McKechnie Sargent) (12/12/87)
In article <1949@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes: >In article <555@ndsuvax.UUCP> ncbauers@ndsuvax.UUCP (Michael Bauers) writes: >>But the address of the array's pointer (what this person wanted to know) >>should be &a. > >Are you saying that "&a" should mean "&(&a[0])"? This doesn't make sense, as >"&a[0]" is not an lvalue. On a "prior art" note, VAX C allows objects like &3, even though 3 is not an lvalue. Because VMS is ruled by Fortran, most VMS services and library entries expect everything passed by reference, even constants: as a convenience to C programmers calling VMS routines, the expression &3 means "cons up an anonymous int whose value is 3; value of the expression is the address of the anonymous int." So &a /could/ be given an analogous interpretation, one at variance with your preference. >address of an entire array entity (which differs from the address of the first >element in exactly the same way that the address of a structure differs from >the address of its first member), and this is exactly the problem that X3J11 >has fixed by legalizing "&a". Um, no. Given an object, s, of type "struct s", &s + 1 does NOT refer to the second element in the struct. Address arithmetic just doesn't "make sense" with structures the same way that it does with arrays. > >Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint Steven Sargent (sarge@scam.berkeley.edu)
blarson@skat.usc.edu (Bob Larson) (12/12/87)
In article <5308@zen.berkeley.edu> sarge@scam.berkeley.edu (Steven Brian McKechnie Sargent) writes: >On a "prior art" note, VAX C allows objects like &3, even though 3 is not an >lvalue. You mean Primos C isn't the only one with the "extention"? Primos C also does some bogus things with casts in procedure calls to "fortran" (anything other than C must be declared fortran). A code fragment: fortran void tnou(); /* a routine from the standard library */ tnou((char [])"hello world", &(short)11); The (char []) cast is needed. Note you can also take the address of a cast expression. Bob Larson Arpa: Blarson@Ecla.Usc.Edu blarson@skat.usc.edu Uucp: {sdcrdcf,cit-vax}!oberon!skat!blarson Prime mailing list: info-prime-request%fns1@ecla.usc.edu oberon!fns1!info-prime-request
chris@mimsy.UUCP (Chris Torek) (12/12/87)
>In article <555@ndsuvax.UUCP> ncbauers@ndsuvax.UUCP (Michael Bauers) writes: >>The address of the array a[10] is just a. The address of the first element >>is also a (for single dimension arrays). This is already confused. >>The first element is *a. But the address of the array's pointer `The address of the array's pointer' is even more confused. >>... should be &a. In article <1442@houdi.UUCP> marty1@houdi.UUCP (M.BRILLIANT) writes: >Huh? I tried writing a C program on UNIX(tm ATT) that referenced &a, >and got the message "warning: & before array or function: ignored." >That says there's no such thing as &a. Given the declaration int a[10]; the following is true: 0. &a is currently illegal 1. &a will be legal in the near future. 2. In an expression, except as a target of sizeof, `a' and `&a[0]' have identical meanings, namely a value of type `pointer to int' that points to the first element of `a' (a[0]). 3. In an expression, `&a' will be a value of type `pointer to (int [10])' that points to the array `a'. Hence `*&a' will be a value of type `int [10]', which, in all expression contexts except as a target of sizeof, is immediately converted to a value of type `int *' (a.k.a. `pointer to int') that points to the first element of that array (here &a[0]). Thus `*&a' will mean the same thing as `a'. Hence, in the near future, one will be able to write the following: f1() { int z[4][10]; int (*p)[10]; int i, j; p = g() ? &z[0] : &z[2]; for (i = 0; i < 2; i++) for (j = 0; j < 10; j++) p[i][j] = (i + 1) * j; ... } At present, it is necessary to code this using casts (because &z[0] elicits warnings or errors about & before array), or using code like the following (with a cast version in comments): f2() { int z[4][10]; /* int (*p)[10] */ int *p; int i, j; /* p = (int (*)[10])(g() ? &z[0][0] : &z[2][0] */ p = g() ? &z[0][0] : &z[2][0]; for (i = 0; i < 2; i++) for (j = 0; j < 10; j++) /* p[i][j] = (i + 1) * j */ p[i*10 + j] = (i + 1) * j; ... } -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
randy@umn-cs.cs.umn.edu (Randy Orrison) (12/13/87)
In article <5308@zen.berkeley.edu> sarge@scam.berkeley.edu (Steven Brian McKechnie Sargent) writes: >In article <1949@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes: >>address of an entire array entity (which differs from the address of the first >>element in exactly the same way that the address of a structure differs from >>the address of its first member), and this is exactly the problem that X3J11 >>has fixed by legalizing "&a". > >Um, no. Given an object, s, of type "struct s", &s + 1 does NOT refer to the >second element in the struct. Address arithmetic just doesn't "make sense" >with structures the same way that it does with arrays. Um, yes. Given an object, s, of type "struct snarf" or "array [n] of gonk", &s + 1 is a pointer to the next object of the same type in memory. Note that in the case of arrays, &s + 1 is VERY different from the much more common &s[0] + 1, which is the next element of the array. (There is nothing that corresponds to this for structures, execpt &s[0]->firstelement). In BOTH cases &s + 1 does NOT refer to the second element. Nothing in that expression talks about elements, and there's no way for the compiler to know where to find the second element (whether s is a struct or array). Now - the reason that you are confused: The C that Karl and I are talking about is not the same C as you are used to. This is ANSI C, not K&R, not pcc, not H&R. Now, I have a question: this all makes sense to me if you have a variable of type pointer to array { char (*s)[10] } but how does this apply when your variable is an array itself { char s[10] }? I suppose it makes sense... is this right: With declarations (on the stack, contiguous in memory...) char s[16]; char t[16]; Is it true that: *(&s + 1) == t (assuming array comparisons)? Arg. Well, they may not be first class, but they're moving up in the world... -randy-- Randy Orrison, University of Minnesota School of Mathematics | UUCP: {ihnp4, seismo!rutgers, sun}!umn-cs!randy | (hello?) ARPA: randy@ux.acss.umn.edu BITNET: randy@umnacca | "I need a unit to sample and hold, but not the angry one: a new design."
marty1@houdi.UUCP (M.BRILLIANT) (12/14/87)
In article <9735@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes: > ... in the near future, one will be able to write the following: > ... > p = g() ? &z[0] : &z[2]; > ... > At present, it is necessary to code this using casts (because &z[0] > elicits warnings or errors about & before array), or using .... Not so on the vax-785 with SV_R2 I'm logged in on now. I can write ... char *a, b[14]; ... a = &b[3]; ... without getting any complaints from the compiler. It does what I want, too: skips the beginning of the array. Writing &b without an index in brackets still draws a warning from the compiler that & before an array is ignored. The storage location where the array begins is known to the compiler by the name b, but since that address is not accessible as data at run time, &b has no meaning. Of course, writing &a draws no warnings, because a is a pointer, and has both a value and a location where the value is stored. M. B. Brilliant Marty AT&T-BL HO 3D-520 (201)-949-1858 Holmdel, NJ 07733 ihnp4!houdi!marty1
ncbauers@ndsuvax.UUCP (Michael Bauers) (12/15/87)
To all who had to read the incorrect drivel I wrote...I apologise. apparently &a is not the standard way to get at the adress of the pointer to the array. I had done &x (where x is an integer var.), before and it worked fine, but &a (where a is an array) does not do the same thing according to sources wiser than myself. Would someone care to comment why &a does not behave like &x does? [-----------------------------------------------------------------------] [ Michael J. Bauers ( senior Computer Science at NDSU ) ] [ Reply to: NU100356@NDSUVM1 or ncbauers@ndsuvax.UUCP ] [ For God so loved the world that he gave his only son so that whoever ] [ believes in him will not perish, but shall have eternal life. ] [ Disclaimer: Frankly I do not think NDSU cares what I think, ] [ or even that I think at all. ] [-----------------------------------------------------------------------]
chris@mimsy.UUCP (Chris Torek) (12/15/87)
>In article <9735@mimsy.UUCP> I wrote: >>... in the near future, one will be able to write the following: [an important line deleted here] >> p = g() ? &z[0] : &z[2]; In article <1445@houdi.UUCP> marty1@houdi.UUCP (M.BRILLIANT) writes: >I can write > char *a, b[14]; > a = &b[3]; >without getting any complaints from the compiler. Yes, but you deleted my declaration for z: int z[4][10]; >Writing &b without an index in brackets still draws a warning from the >compiler that & before an array is ignored. Exactly: and it WILL NOT once your compiler is compliant with the ANSI X3J11 standard. >The storage location where the array begins is known to the compiler >by the name b, *WITH WHAT TYPE?* Answer *THAT* and you may see what &b will mean. >but since that address is not accessible as data at run time, &b has >no meaning. NO! It has no meaning *NOW*; it *WILL* in the *FUTURE*! AAAAAAARGH! (There, I feel better now.) Given the declaration `char b[14]', the value of &b will be the same as the value of &b[10] with one important difference: The TYPE of &b[0] is `char *'; the TYPE of &b will be `char (*)[14]'. [Aside: the exact representation of the two values may differ, depending on, e.g., type tag bits. This is irrelevant to the future language definition.] This is the key: C is a typed language. B is not; B has `words'. C is; C has `pointer to char' and `pointer to pointer to char' and `pointer to int' and . . . and each type is different and mutually incompatible. Two expressions with the same value but different types are different. The very quote above, `The storage location where the array begins...' shows that you are thinking of C as an untyped language. This is wrong. Every value has a type. Given the declaration `int a[N};', the difference between `&a[0]' and `&a' is the type of the expression. Expressions are <type,value> pairs. Leaving out either piece of the pair gives you an improper expression: something that is not C. Remember that: <type,value> pairs. The difference between &a[0] and &a is (will be) in the `type' half. (Now *that* has *got* to be clear....) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
dik@cwi.nl (Dik T. Winter) (12/15/87)
Why is it that so many people cannot read and omit the saliant point when answering? To wit: In article <1445@houdi.UUCP> marty1@houdi.UUCP (M.BRILLIANT) writes: > In article <9735@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes: > > ... in the near future, one will be able to write the following: > > ... > > p = g() ? &z[0] : &z[2]; > > ... > > At present, it is necessary to code this using casts (because &z[0] > > elicits warnings or errors about & before array), or using .... > > Not so on the vax-785 with SV_R2 I'm logged in on now. I can write > ... > char *a, b[14]; > ... > a = &b[3]; > ... > without getting any complaints from the compiler. It does what I want, > too: skips the beginning of the array. > The declarations in the original article were: > int z[4][10]; > int (*p)[10]; and that makes a lot of difference! -- dik t. winter, cwi, amsterdam, nederland INTERNET : dik@cwi.nl BITNET/EARN: dik@mcvax
chris@mimsy.UUCP (Chris Torek) (12/15/87)
In article <9775@mimsy.UUCP> I wrote >... the value of &b will be the same as the value of &b[10] change `10' to `0' >... Given the declaration `int a[N};', change `}' to `]' (Well, I was on an unfamiliar terminal.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/15/87)
In article <329@dlhpedg.co.uk> cl@.co.uk (Charles Lambert) writes: >... the name of the array being a synonym for its address; ... By oversimplifying, you got it wrong. The name of an array is converted IN SOME CONTEXTS to a pointer to the first element of the array. These contexts do not include as the operand of the sizeof operator nor (as of ANSI C) as the operand of &. As Chris Torek remarked, "address" should not be bandied about when talking about C; C is a typed language, and its pointers have definite types. Understanding the &array issue requires being careful about type distinctions.
throopw@xyzzy.UUCP (Wayne A. Throop) (12/18/87)
> References: <555@ndsuvax.UUCP> > ncbauers@ndsuvax.UUCP (Michael Bauers) > What they > had meant to say I think was 'The adress of the array's pointer.' No, they really meant the address of the array. > The article > I was responding to was talking about taking the address of an array. The > address of the array a[10] is just a. This is incorrect. Detailed discussion below (which I hope hits a few points not already covered by others). > References: <126@citcom.UUCP> ... <3137@tut.cis.ohio-state.edu> > lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) >>, marty1@houdi.UUCP (M.BRILLIANT) >> That says there's no such thing as &a. > This is like taking the address of a constant, say &0435241250, > which of course is silly. This is common folklore, that "arrays are constants" or "array names represent constants". This is true, but only for an unusual meaning of the word "constant", involving "unchanging for a specific (but possibly varying) lifetime". "Constant" things are more normally thought of as being unchanged at least as long as a process execution, normally longer, and this is not true of arrays. The address of the first element of a particular instance of an array is a value that does not change for the lifetime of that instance of that array. But that's not the same thing as a "constant", at least, not as most people think of constants. Think of automatic arrays, for example. By the way, the draft X3J11 standards document has changed the standard way of talking about arrays. In the terms as defined in the document, it is incorrect to say that arrays are "constants", or that array names evaluate to constants, or any of those common sayings. In fact, arrays are even lvalues as the term is defined in the standard. (It turns out that "lvalue" will no longer mean "may be assigned to". Arrays are examples of "non-modifyable lvalues".) > Why do programmers want to do this? It is most useful in dealing with arrays of arrays, or in dealing with heaplike allocation of array objects. > Do other > languages let you do this? Yes. Pascal, Modula, PL/I (sort of), and more less-famous Algol variants than you can shake a stick at. > References: <329@dlhpedg.co.uk> > cl@dlhpedg.co.uk (Charles Lambert) > Any object, of any type (integer, structure, array, etc.), has an address. Right. > Usually, if it is an object that occupies several words of memory, it is the > address at which it begins. Wrong, at least if you are talking about how addresses are treated in C. There is no such thing as "begins" and "ends" in terms of addresses of C objects. There is just the address of the object, period. See my note about the usage of the term "address" in the C language below, in response to Doug Gwyn. > In C, the address of an array is the same as the address of its first > element (array[0]). No. Because the address of the array and the address of the first element *IN* *C* have different results when indirected or incremented. > If you want to set up a pointer to the array, you > get its address simply by naming it. Hence: > pa = array; /* pa now contains the address of "array" */ No. Unless a type conversion not shown is implied by the assignment, pa contains the address of the first element of array. > Now this is a slight quirk in C - the name of the array being a synonym for > its address; This is not a quirk of C. The name of an array is a synonym (but not always) for the address of its first element, not for the whole array. The two are distinct things. K&R are very careful here, they do *NOT* say that the name of an array is a synonym for that array's address. > So we get back to the discussion from whence we came: why can't we be > consistent and get the address of an array by > pa = &array; ? > To which the answer is: you can, with some compilers. But most often, compilers that allow this construct do it incorrectly, and make it a synonym of pa = array; which is, of course, incorrect. ANSI C compilers will get this correct. > References: <6835@brl-smoke.ARPA> > gwyn@brl-smoke.ARPA (Doug Gwyn ) > As Chris Torek remarked, "address" should not be bandied about > when talking about C; C is a typed language, and its pointers > have definite types. Understanding the &array issue requires > being careful about type distinctions. Actually, K&R sort-of use "address" and "pointer" to refer to indirectable-and-arithmetic-able rvalues and lvalues respectively. Thus, I don't think it is wrong to talk about "addresses" in C. But you'd better remember that you aren't talking about address-of-anything. In C, you are talking about address-of-something-in-particular. (Yes, I'm ignoring (void *) and function pointers for now. So sue me.) Remember, in C, "address" is a technical term, just as "pointer" is. Or at least, that's the way I tend to use it. > References: <15869@watmath.waterloo.edu> > rbutterworth@watmath.waterloo.edu (Ray Butterworth) > Isn't it amazing how many people are confused by such a simple > concept as the address of an array? If only K&R hadn't tried > to "optimize" out this idea, I don't think there would be any > of this confusion (at least no more than there is for the > concept of the address of a structure). Hear, hear! -- "Technical term" is a technical term for a common word or phrase whose meaning is, in some contexts, distorted beyond mortal comprehension. --- Hal Peterson ihnp4!cray!hrp -- Wayne Throop <the-known-world>!mcnc!rti!xyzzy!throopw
gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/19/87)
In article <569@ndsuvax.UUCP> ncbauers@ndsuvax.UUCP (Michael Bauers) writes: >Would someone care to comment why &a does not behave like &x does? In ANSI C, it does! In some older C compilers, &a was illegal, and in others &a was treated like plain a (i.e. as &a[0]).
lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) (12/21/87)
After think about array address a bit, I see how silly I have been in thinking they were silly. Most of this is obvious, but here it is anyway. Maybe someone else will benefit from this too. Here is what I hope is a correct interpretation of array address. This is mostly borrowed from other postings. Thanks to Torek, Throop, Butterworth, Gwyn, and Heuer, etc. 1) Every object has an address. Arrays are objects, so they must have addresses. 2) The name of an array is a synonym for the address of the first element of the array. This is only a CONVENIENCE so you can write: for (p = name; p < &name[NTHINGS]; p++); instead of having to write: for (p = &name[0]; p < &name[NTHINGS]; p++); 3) The name of an array is NOT a synonym for the address of the array. 4) When you indirect a pointer to an array, you get an ARRAY. 5) When you increment (decrement) a pointer to an array, you point to the "next" ("previous") array. 6) Given: int ident[4]; The value of &ident might NUMERICALLY happen to equal &ident[0] but they are different because they have different TYPES. &ident is of type (int *)[4], and &ident[0] is of type (int *). 7) Given: int ident[2][4], (*pai)[4] = &ident[0]; pai++ would be equal to &ident[1] pai = &ident[3]; pai-- would be equal to &ident[2]; 8) ANSI C will allow: int ident[2][4], (*pai)[4] = &ident[0]; but not: int ident[2][4], (*pai)[5] = &ident[0]; Now, a question on ANSI C. Will you be able to do this: int ident[2][4]; int (*pai)[4] = &ident[0]; int (*pbi)[4] = &ident[1]; code that manipulates ident[0] *pbi = *pai; Thanks for all the info. -- Larry Cipriani AT&T Network Systems at cbosgd!osu-cis!tut!lvc Ohio State University
domo@riddle.UUCP (Dominic Dunlop) (12/23/87)
In article <9735@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: [Quotes from other postings deleted] >Given the declaration > > int a[10]; > >the following is true: > > 0. &a is currently illegal > 1. &a will be legal in the near future. [Further points and examples deleted] Well, I didn't agree with point 1. Looking at the November 9 draft of the proposed ANSI standard, I found that it says concisely in 3.3.3.2 -- Address and Indirection Operators: The operand of the unary & operator shall either be a function designator or an lvalue that designates an object that is not a bit-field and is not declared with the register storage class specifier. This confirmed my prejudice, namely that & applied to an object of array type is an error. But then I looked in 3.2.2.1 -- Lvalues and function designators: An lvalue is an expression ... that designates an object... A modifiable lvalue is an lvalue that does not have array type... Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array of characters, an lvalue which has type ``array of type'' is converted to an expression that has type ``pointer to type'' that points to the initial member of the array object and is not an lvalue. To summarize, an array can now be an lvalue, albeit not a modifiable one, and consequently, the & operator can be applied to it. The draft does not explicitly say what happens when the operator is so applied. I assume that the address of the whole array is delivered, and that the type of the result is ``pointer to array of ...'' What on earth are the consequences of this, and why was it done? Who needs a ``pointer to array of ...'' Enlightenment, please... -- Dominic Dunlop domo@sphinx.co.uk domo@riddle.uucp
throopw@xyzzy.UUCP (Wayne A. Throop) (12/24/87)
> lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) > Summary: do I have it right now? Yep. But I can't resist clarifying one little nit. Something in my upbringing, I think. > 2) The name of an array is a synonym for the address of > the first element of the array. This is only a CONVENIENCE > so you can write: > for (p = name; p < &name[NTHINGS]; p++); > instead of having to write: > for (p = &name[0]; p < &name[NTHINGS]; p++); This is *right*, sort of, but I wouldn't put it this way, and putting it this way gives me an itchy sensation I just have to scratch. The way I think of it is not that an array name is a synonym for the address of the first element of the array, but that any array object, when encountered in an expression, is converted to the address of the first element in the array (except when object of sizeof or '&' operators). Note: "is converted", not "is a synonym". This way of thinking about it handles arrays of arrays nicely, while the alternate requires one to consider aa[N] to be the "name" of an array, which is not quite right. A small nit, perhaps, but I think it helps to think of it this way. Further, this isn't so much a convenience as it is a direct fallout of the definition of the subscripting/address-arithmetic equivalence in C. Personally, I would have done it just the way Larry describes above, and define pointer arithmetic in terms of array subscripting. But K&R in their wisdom did the reverse: subscripting is defined in terms of pointer arithmetic. This means that an array object, when used in a subscripting expression, *MUST* be converted to the address of the first element of the array for the subscript operation to work at all. K&R just extended this to become the default situation: array objects in most expressions are converted as they are in subscript expressions. Again, a small nit, but [etc, etc]. -- There are some forms of insanity which, driven to an ultimate expression, can become new models of sanity. --- Bureau of Sabotage {Frank Herbert} -- Wayne Throop <the-known-world>!mcnc!rti!xyzzy!throopw