Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!utfyzx!sq!msb From: msb@sq.UUCP Newsgroups: comp.lang.c Subject: Re: static char (*b)[6]; /* an unusual declaration */ Message-ID: <1987Jun13.205040.24186@sq.uucp> Date: Sat, 13-Jun-87 20:50:40 EDT Article-I.D.: sq.1987Jun13.205040.24186 Posted: Sat Jun 13 20:50:40 1987 Date-Received: Sun, 14-Jun-87 02:00:27 EDT References: <761@bsu-cs.UUCP> Reply-To: msb@sq.UUCP (Mark Brader) Organization: SoftQuad Inc., Toronto Lines: 104 Checksum: 48635 Summary: Pointer to arrays of 6 chars each. Rahul Dhesi (dhesi%bsu-cs@iuvax.UUCP) writes: > What is the meaning of the following declaration? > > static char (*b)[6]; b is what is commonly called a "pointer to array of 6 chars", but better described as "pointer to arrays of 6 chars" (each). b is static. When C sees a function definition beginning like this: func(x, b) char x[], b[][6]; { the declaration is translated* (only because these are function parameters and therefore not allowed to really be arrays) to char *x, (*b)[6]; The object you describe is of the same type, but static. > The compiler and lint checker used by the magazine columnist seem to > treat the declaration of b as equivalent to char ** which is isn't. > main() > { > static char (*b)[6]; /* an unusual declaration */ > static char a[] = "Hello"; > char *c = a; > char **d = &c; So far so good, c and *d are both pointers-to-character (or as I prefer, pointers-to-characters) indicating the H in "Hello". > b = d; /* So b == d ... Watch. */ The two sides are incompatible pointer types, so there really should be a cast here, but I'll get back to that later. Anyway, what this is saying is that the value in d, which is the address of the pointer c, is to be stuffed into b. Well, what happens when you then try *b? It treats the 6 bytes beginning at the variable c as if they were an array of characters! No wonder different values are printed on different machines. What the coder presumably meant is: b = *d; NOW *b and *d are pointing to the same place -- but to a different number of characters. *d points to the H, *b to the whole array "Hello". Further indexing through either pointer does produce a char, so they are similar in that respect, but not identical just the same. Remember that *x is the same as x[0], and consider: d is a pointer to pointer to char(s) which points to c d[0] is a pointer to char(s), equal to c d[0][0] is the char 'H', same as c[0] d[0][1] is the char 'e', same as c[1] d[1] would be garbage obtained by treating the memory location following d as a pointer b is a pointer to array(s) of 6 chars b[0] is an array of 6 chars containing "Hello" b[0][0] is the char 'H' b[0][1] is the char 'e' b[1] would be garbage obtained by treating the memory location following the "Hello" bytes as an array b[1][0] would be the char after the closing null in "Hello" (if there is one, rather then running off memory) The printf of *b is legitimate, or would be if b had a reasonable value; since *b has an array-of-chars type it is converted to pointer-to-char(s) on being passed to a function. Now about that cast. In ANSI C as currently drafted, it is a requirement that assignments involving pointer conversion be explicitly specified by cast. (That is, the "(type)" syntax.) Some modern compilers at least warn about such assignments now. Here, *d has type "pointer to char", while b is what I said above; therefore b = *d involves a conversion and should really be written b = (char (*)[6]) *d; > Other code fragments omitted. The columnist continues, "...This means > that *b is a constant and while (b) can be modified, *b never will > change its original value. Thus, setting b = d does not mean that > *b == *d. Also, while *b is treated as a constant (unchangeable), the > value of b can vary." This starts to make no sense. It is true that for a particular value of b, it is impossible to assign to *b, but only because *b has array type. (Assigning to *d would be assigning to c, on the other hand). But it is certainly possible to assign to b again, or to **b while b is held constant. If the columnist is in the habit of confusing d and *d, I would suggest that the column probably isn't worth reading. (But I haven't seen it myself). Mark Brader, SoftQuad Inc., Toronto, utzoo!sq!msb #define MSB(type) (~(((unsigned type)-1)>>1)) *For my opinions on this alleged syntactic sugar, see Karl Heuer's article. I agree with him that it should be eliminated in the new syntax. But that's another story.