This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Type promotion bug?

Specific pointer -> generic pointer -> boolean (i.e. implicit compare to 0) seems not to work as expected.

void main()
{
  char* p;
  char* q;
  char xdata* xp = NULL;

  bit fail = FALSE;

  // This fails.
  if ( p = xp )
  {
    fail = TRUE;
  }

  // This is ok.
  if ( ( q = xp ) == NULL )
  {
    fail = TRUE;
  }
}

Parents
  • It's always interesting to discuss whether an implementation of a C compiler conforms to the standard or not. Here is my 2 cents.
    The ISO C 1999 says:

    An integer constant expression with the value 0, or such an expression cast to type
    void *, is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.
    ...
    Conversion of a null pointer to another pointer type yields a null pointer of that type. Any two null pointers shall compare equal.


    Let's see if C51 conforms to that. Forgive me if I make mistakes here, since I only did C166.
    It's easy to satisfy the first requirement: a null pointer can't point to an object in C program. Just make sure that the linker doesn't put anything to where the null pointers point.
    The second requirement:

    if ( (void*)0 != (void xdata*)((void*)0) )
        printf("Oops! This is not ISO C behaviour.");
    
    From the previous discussion I got the impression that this code will do the 'oops'.
    My point is that it's probably OK to break standard conformance in some places if it's justified by performance/simplicity/etc considerations. After all, if one wants standard C behaviour, they can limit themselves to using generic pointers only.

    - mike

Reply
  • It's always interesting to discuss whether an implementation of a C compiler conforms to the standard or not. Here is my 2 cents.
    The ISO C 1999 says:

    An integer constant expression with the value 0, or such an expression cast to type
    void *, is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.
    ...
    Conversion of a null pointer to another pointer type yields a null pointer of that type. Any two null pointers shall compare equal.


    Let's see if C51 conforms to that. Forgive me if I make mistakes here, since I only did C166.
    It's easy to satisfy the first requirement: a null pointer can't point to an object in C program. Just make sure that the linker doesn't put anything to where the null pointers point.
    The second requirement:

    if ( (void*)0 != (void xdata*)((void*)0) )
        printf("Oops! This is not ISO C behaviour.");
    
    From the previous discussion I got the impression that this code will do the 'oops'.
    My point is that it's probably OK to break standard conformance in some places if it's justified by performance/simplicity/etc considerations. After all, if one wants standard C behaviour, they can limit themselves to using generic pointers only.

    - mike

Children
  • My point is that it's probably OK to break standard conformance in some places if it's justified by performance/simplicity/etc considerations. After all, if one wants standard C behaviour, they can limit themselves to using generic pointers only.

    I guess that this is the nub of the matter. If you write standard C code, you will always be getting generic pointers and, hence, standard C behaviour. Memory specific keywords are Keil extensions and if you choose to use them it is necessary to understand how they work in some detail.