Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!snorkelwacker.mit.edu!bloom-picayune.mit.edu!news From: scs@adam.mit.edu (Steve Summit) Newsgroups: comp.lang.c Subject: Re: Frequently Asked Array Questions Message-ID: <1991Mar30.081807.21378@athena.mit.edu> Date: 30 Mar 91 08:18:07 GMT References: <1991Mar15.045933.25690@athena.mit.edu> <1991Mar30.060146.10515@cbnews.att.com> Sender: news@athena.mit.edu (News system) Reply-To: scs@adam.mit.edu Organization: Thermal Technologies, Cambridge, MA Lines: 73 In article <1991Mar30.060146.10515@cbnews.att.com> junk1@cbnews.att.com (eric.a.olson) writes: >>20. So what is meant by the "equivalence of pointers and arrays" in C? >> >>A: An identifier of type array-of-T which appears in an expression >> decays into a pointer to its first element; the type of the >> resultant pointer is pointer-to-T. > > Exactly what kind of expression? > Not, for instance, one where an lvalue is expected... now: Actually, the quoted sentence from the FAQ list has a significant error in it, and should instead read: An *lvalue* of type array-of-T which appears in an expression decays into a pointer to its first element... This is The Rule, though it does have three exceptions, which are not mentioned in the abridged FAQ list from which Eric quoted. The exceptions, as described in the long list, are "when the array is the operand of the sizeof() operator or of the & operator, or is a literal string initializer for a character array." (The second exception is mildly equivalent to Eric's "not where an lvalue is expected.") > Today, I ran across a situation where a peer had: > char array[7]; > if (array == 0) > No compiler we have complains about it. > They complain about a test for equality with any other constant > but 0, but even then, only that it is an illegal pointer/integer > combination. (I understand that difference). The conditional expression if (array == 0) does not match any of the three exceptions, so the compiler dutifully generates a pointer to the first element of the array, and then compares it to the null pointer, which is, as Eric correctly observes, guaranteed not to succeed. When exposed to the light of day like this, this behavior does seem odd, but the compiler is just blindly following the rules, as compilers are wont to do. A legitimate message from the compiler in this case would be "warning: constant in conditional context." (A more interesting message might be "warning: comparison of constants.") Standard lint, however, does not make this diagnosis, presumably because it does not treat array names as the constants they really are. (In this case, the array name is only quasi-constant, because its storage class is auto. However, lint doesn't complain about comparisons of statically-allocated array names, either.) I've added this case to my lint wish list. > the following is clearly legal: > { > char x[7]; > char *p; > for (p=x+3; p != x; --p) > something; > } > therefore, testing an auto array name for equality to a constant > is legal as well, since if you reduce the types you have the same > types in both cases. Actually, this example is slightly different. The types are the same, but it is not "testing an auto array name for equality to a constant," since p is a variable. Steve Summit scs@adam.mit.edu