Path: utzoo!utgpu!utstat!jarvis.csri.toronto.edu!rutgers!cs.utexas.edu!sun-barr!decwrl!decvax!ima!haddock!karl From: karl@haddock.ima.isc.com (Karl Heuer) Newsgroups: comp.lang.c Subject: Re: typedefing arrays Keywords: kludge hack bogus Message-ID: <13598@haddock.ima.isc.com> Date: 6 Jun 89 00:14:28 GMT References: <4636@alvin.mcnc.org> Reply-To: karl@haddock.ima.isc.com (Karl Heuer) Organization: Interactive Systems, Boston Lines: 48 In article <4636@alvin.mcnc.org> spl@mcnc.org (Steve Lamont) writes: >Is it possible to do something like > typedef int vertex[3]; > vertex *v; > v = ( vertex *) malloc( sizeof( vertex ) * some_number ); Yes, provided your compiler supports the concept of pointer-to-array.$% Your example would be equivalent to the non-typedef code: int (*v)[3]; v = (int (*)[3])malloc(sizeof(int [3]) * some_number); In either case, accessing an element is done via (*v)[i]. I presume this is the syntax that you found "inelegant". That's a matter of taste, I guess, but it's exactly analogous to (*fp)(arg) for function pointers@, and (*sp).mem for struct pointers, the only difference being that this last one is so common that it has the builtin synonym "sp->mem". Actually, the above paragraph applies to single-object allocations. Since you're allocating a vector (of length some_number) of these vertices, you can reference the i'th coordinate of the n'th vertex in the vector by simply writing "v[n][i]". Looks a lot like a two-dimensional array, right? Not surprising, since in fact (int (*)[3]) is the type of the rvalue that results from a two-d array of type (int [M][3]) after the array decays into a pointer. Now, if the three elements (despite having a common type) are conceptually different and noninterchangeable, so you'd always be referencing them with a constant index, then you should probably stick with the struct definition. If it really needs to be an array, and the notation still bothers you (or if you want to ensure it will port to compilers that don't support array pointers), I recommend "typedef struct {int coord[3];}", which allows you to reference the elements with "v->coord[i]" (single-object allocation) or "v[n].coord[i]" (multiple-object allocation).# Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint ________ $ Note that pointer-to-array-of-int is *not* the same thing as pointer-to- -int-element-of-array, which is much more common. The latter is what you get when you write "p = &a[i]", or when you let an array-of-int decay into a pointer. The former is a pointer to the *entire array* itself, is a very rarely used type, and behaves differently with, e.g., the "++" operator. % I believe some older compilers don't support it. And I know there are many that allow you to have a pointer-to-array, but refuse to believe that "&a" is a legal way to generate such an object. (Fixed in ANSI C.) @ Actually, X3J11 has rewritten the rules so that it's now legal to invoke a function via a pointer without explicitly dereferencing: fp(arg) is legal in ANSI C. Personally, I prefer to maintain the distinction between functions and function-pointers. # This, together with "#define x coord[0]" etc., can be quite useful.