On Fri, Mar 07, 2008 at 03:28:08PM +0100, Vincent Lefevre wrote: > On 2008-03-06 10:08:34 +0000, Nicolas Bernard wrote: > > You are missing my point. They EVALUATE to pointers, but they are > > not pointers. > > No, the point is that the test is performed on the pointer itself. > If you think that the test array == NULL is wrong, then for the same The test isn't wrong, it's just not particularly useful, and slightly inefficient. The warning from gcc rightly points this out. > > By "it doesn't make sense", it was not implied that the code was > > wrong, only that it is unneeded > > Not much less unneeded than assertion checking and debug messages. Quite true; in this case, none of the above are necessary or useful, since the test is being applied to a constant pointer which is guaranteed to be non-NULL. In the general case, all are useful. In this specific case, they are all not useful. Let's take another quick look at the C standard: They are arrays, but in expressions, they evaluate to pointers (with a few exceptions). More precisely: [ISO C99, 6.3.2.1] [#3] Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ``array of type'' is converted to an expression with type ``pointer to type'' that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined. There are a couple of extremely important things to note here. The first one is the phrase "is converted" -- for the term "converted" to be applicable, it means that one thing is being changed to a second thing, which is different and distinct from the first thing. If the two things are already the same, then conversion is impossible and an incorrect terminology. The second thing to note is the phrase "and is not an lvalue." Here, we mean that the pointer can not be reassigned; i.e. it is a constant. This normally is not true of generic pointers. It should be clear that an array is NOT simply a pointer. They are different from pointers in the generic case in the following ways: - they can not be lvalues - they are constant - they typically may only point to memory allocated in specific regions of memory (e.g. the BSS, as opposed to the stack or heap), whereas pointers may point anywhere [this may be dependent upon implementation] - they can not ever be NULL While the name of an array is converted to a pointer type, and is equivalent to a pointer type in most cases, it is not, strictly speaking, the same as a pointer. And thus not all operations which one can do to a pointer make sense in the same way as they would for a pointer, when applied to an array. This case is such a case. > > and resulting of a confusion between an array and a pointer. > > There is no confusion. The code could also have been obtained by > a copy-paste where the test was needed before. ...which sounds an awful lot to me like the programmer was confused. > And there is nothing wrong with this test. That's not quite true; the thing which is wrong with it is that it needlessly produces a compiler warning which is not interesting or necessary for this case. Again, in the general case the test is fine; but in this specific case it is useless and produces noise in the form of compiler warnings, which can easily be eliminated by rewriting the check. Thus it is undesirable. > You're wrong. Making such bald-faced, confrontational statements is inflamatory and rude. And in this case, it happens to be untrue as well. > There are cases where the test is really necessary (in And this is not such a case. > So, the warning is useless and bad. The warning is only useless in this case, because the check is pointless. The warning itself is perfectly legitimate. > array and &array do not evaluate to the same pointer. > array is transformed into &array[0]. That statement is trivially proven to be incorrect with a tiny little C program: $ cat ptr.c #include <stdio.h> int main(int argc, char **argv) { char name[] = "foo"; printf("value of name = %0x\n", name); printf("value of &name = %0x\n", &name); printf("value of &name[0] = %0x\n", &name[0]); return 0; } $ ./ptr value of name = bfe50f60 value of &name = bfe50f60 value of &name[0] = bfe50f60 They do indeed evaluate to the same pointer, always. I didn't feel like writing the malloc code to also check dynamically allocated strings, but I'm pretty certain the same is true for those as well. The only thing I can think of which I'm not sure if it might be different is arrays of structs... I have a vague notion that they may store metadata about the organization of the structure before the first element of the array; but that might be an implementation-specific detail, or I might just be on crack... ;-) -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0xDFBEAD02 -=-=-=-=- This message is posted from an invalid address. Replying to it will result in undeliverable mail due to spam prevention. Sorry for the inconvenience.
Attachment:
pgpKIjVbrOeoV.pgp
Description: PGP signature