On Mon, 1 Mar 2004, Erik Petrich wrote:
> On Mon, 16 Feb 2004, Story, Lenny wrote:
> > Greetings,
> > I have been noticing some funnyness when using generic pointers. I dont
> > believe that any of this are bugs, just different consquences in using
> > pointers with type fields.
> > 1. Comparing to NULL performs a comparison of the type field. This then
> > presents an issue where the pointer VALUE could be 0 but the type is not.
> > The comparison Fails, and presents a behavior that is not expected. (or is
> > it?)
> > 2. It seems that because of #1 comparisons against NULL should use 0. This
> > would perform a numeric compare rather than a pointer compare and result in
> > correct behavior.
> > 3. Libraries use the (void *)0 NULL, so these appear to work if used
> > against true NULL....
> > 4. Should i have 4 varients of NULL ?
> > #define XNULL (xdata void *)0
> > #define CNULL (code void *)0
> > #define INULL (idata void *)0
> > #define NULL (void *)0
> > What is the intent of comparisons against NULL in your minds ? It is
> > possible im making a big deal out of nothing...if so, how should i be
> > viewing this ?
> > Thanks in advance for the clarification...
> > -Lenny
> Section 184.108.40.206 of ISO/IEC 9899:1999 (this is C99; I haven't yet been able
> to track down a copy of the previous C standard) states that:
> (void *)0 is called a null pointer constant.
> The pointer resulting from the conversion of a null pointer constant to
> another pointer type is called a null pointer.
> Any two null pointer shall compare equal.
> However, the standard C environment also envisions a unified memory space.
> I believe SDCC's generic pointers (which provides the appearance of a
> unified memory space) work correctly if used exclusively. The problem
> seems to be with pointers to specific memory spaces. Since this is a
> nonstandard extension to C, we can implement anything we want, but it
> would be good to try to keep its spirit, if practical.
> Currently, if a pointer of any type is compared to a a literal generic
> pointer to void, the literal generic pointer will be cast to the other
> pointer's type before the comparison. So in the following code
> xdata char * xp;
> if (xp == (void *)0) doSomething();
> if (xp == (xdata void *)0) doSomething();
> both conditions are interpreted identically since the (void *)0
> automatically becomes (xdata void *)0 to match xp's type. However, this
> does not help if a pointer is converted to a generic pointer before the
> xdata char * xp;
> char * gp;
> gp = xp;
> if (gp == (void *)0) doSomething();
> if (gp == (xdata void *)0) doSomething();
> These comparisons are not identical.
I've done some experiments with Keil's compiler (8051) as well as
Borland's Turbo C compiler (16-bit x86, large memory model). SDCC's
current behaviour, with respect to NULL pointer comparisons, appears
consistent with these other compilers. In summary:
1) Any pointer (either unqualified, or qualified with some memory space
storage class) can be assigned the value NULL. This pointer can be
compared to the value NULL and the results will be as expected.
2) The value of a pointer qualified with some memory space storage class
can be assigned to an unqualified pointer. However, when the unqualified
(generic) pointer is compared to NULL, the result may be false even if a
comparison of the qualified pointer with NULL returned true.
So my final conclusion is that we don't need to change anything.