<<< Date Index >>>     <<< Thread Index >>>

Re: Little code cleanup



On 2008-03-07 16:23:09 +0100, Nicolas Bernard wrote:
> No, you are still missing my point. Think of how the compiler see the
> code:
> when you write "array" as in
> if (array)
> the compiler just replace "array" by the address of the [beginning of] the
> array. Now, when you write "pointer" as in
> if (pointer)
> the compiler replace "pointer" by code to get the content of pointer
> from the memory then check this value, which is an address.

This is non-sense. The compiler is free to do whatever it wants as
long as it is conform to the C standard. And if it happens that the
address is 0 (addresses are implementation defined), the compiler
must not replace array by 0, otherwise the test would be wrong. And
the value of a pointer does not necessarily correspond to an address
(case of the null pointer).

> While in both case it evaluates to an address (and, from the point of
> view of the programmer, the result is the same), in the first one it is
> known at compile time,

No, it is not necessarily known (e.g. programs may be relocatable).

> > You're wrong. There are cases where the test is really necessary (in
> > the sense that removing it makes the program behave incorrectly),
> > because the expression comes from the preprocessor and is sometimes
> > an array, sometimes a pointer.
> 
> Once again, it is not because you can use pointers and array with the
> same syntax that they are the same thing.

I've never said they are the same thing. Just that they can be used
in the same context.

> That the expression can come from the preprocessor doesn't change
> anything.

This is precisely where one of the problems comes from (FYI, some
warnings have been removed from gcc just because of the use of the
preprocessor).

> > So, the warning is useless and bad.
> 
> Not at all. Or else it is the case with most warnings. For example,
> if (a = b)
> will generate a warning.

If some cases, if (a = b) may be a bug (e.g. the programmer forgot the
second =), and when it is not, this is a very bad style, because most
readers of the code (even those who know C very well) may read that as
if (a == b). So, the warning is completely justified, and it is very
easy to avoid it (and this would make the code more readable and more
maintainable). I expect very few people to disagree with that.

On the other hand, I don't see any problem with:

  if (X)

where X is an array. Moreover, gcc gives a warning for

  if (X == 0)

but not for

  if (X == (void *) 0)

This is completely unintuitive!

> Here for example, you can see the warning as meaning: "the programmer
> created an array but used it as if it was a pointer so he must be
> confused"

There is plenty of code where an array is used as a pointer (including
in Mutt). And in most of it, the compiler doesn't emit any warning.

> or simply as "you can optimize the code here by removing a part of
> the expression" (which the compiler will probably do anyway).

This is also the case for

  if (some_integer_constant_expression)

for which the compiler doesn't emit any warning (at least the latest
versions of gcc -- this wasn't always the case).

> Yes, but I see it as only another proof that macros should be
> avoided because such text substitutions bypass type checking and the
> programmer is then tempted to use them in incorrect ways. That's why
> in C99 it is often cleaner to use static inline functions.

That's true, but sometimes one can't replace a macro by static
inline functions (except by duplicating some parts of the source,
which is something one may want to avoid).

> > array and &array do not evaluate to the same pointer.
> > array is transformed into &array[0].
> 
> If array is a real array (i.e., a static one), it is the same thing.

No, pointer arithmetic is different: 1 + array is different
from 1 + &array. Moreover, the C standard allows the memory
representation and even the pointer size to be different (i.e.
sizeof(array+0) != sizeof(&array)), though no implementations are
known to make such a difference (this would problably break some
non-conforming programs). Read the archives of fr.comp.lang.c and
comp.std.c for more information.

-- 
Vincent Lefèvre <vincent@xxxxxxxxxx> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)