I examined the problem further, using the following code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


/**********************************************************/
/* */
/*   PLI/1 NULL () => SYSNULL ()                          */
/* */
/**********************************************************/

static void pli1_null_to_sysnull (void *pptr)

{
   char *cp = pptr;

   if (memcmp (cp, "\xff\x00\x00\x00", 4) == 0)
   {
      *cp = 0x00;
   }
}


/**********************************************************/
/* */
/*   PLI/1 NULL () => SYSNULL ()                          */
/*        */
/**********************************************************/

static void *pli2_null_to_sysnull (void *ptr)

{
   unsigned int ppli = (unsigned int) ptr;

   if (ppli == 0xff000000u)
   {
      return NULL;
   }
   else
   {
      return ptr;
   }
}


/**********************************************************/
/* */
/*   PLI/1 NULL () => SYSNULL ()                          */
/* */
/**********************************************************/

static void *pli3_null_to_sysnull (void *ptr)

{
   if (ptr == (void *) 0xff000000u)
   {
      return NULL;
   }
   else
   {
      return ptr;
   }
}


int main (void)

{
   char *ptr;

   memcpy (&ptr, "\xff\x00\x00\x00", 4),
   printf ("ptr before pli1...: %p\n", ptr);
   pli1_null_to_sysnull (&ptr);
   printf ("ptr after pli1....: %p\n", ptr);

   memcpy (&ptr, "\xff\x00\x00\x00", 4),
   printf ("ptr before pli2...: %p\n", ptr);
   ptr = pli2_null_to_sysnull (ptr);
   printf ("ptr after pli2....: %p\n", ptr);

   memcpy (&ptr, "\xff\x00\x00\x00", 4),
   printf ("ptr before pli3...: %p\n", ptr);
   ptr = pli3_null_to_sysnull (ptr);
   printf ("ptr after pli3....: %p\n", ptr);

return 0;
}


The results are:

for OPT(2):

ptr before pli1...: FF000000
ptr after pli1....: 0
ptr before pli2...: FF000000
ptr after pli2....: FF000000
ptr before pli3...: FF000000
ptr after pli3....: FF000000

for OPT(0):

ptr before pli1...: FF000000
ptr after pli1....: 0
ptr before pli2...: FF000000
ptr after pli2....: 0
ptr before pli3...: FF000000
ptr after pli3....: 0

so the problem is a problem of the optimization;
and: the cast of the constant to (void *)
- see pli3_... - doesn't help.

Then I tried it again, replacing the 0xFF000000 constants
by 0x7F000000 (which doesn't help me, because PL/1 NULL Builtin
yields 0xFF000000, and that is what I was trying to translate).

But: this time it worked, even with OPT(2).

So the problem is indeed the high order bit of the address value;
C thinks that a comparison with an unsigned int constant having
the high order bit on can NEVER be true. At least the optimizer
at level OPT(2) thinks so and throws away the logic doing such
comparisons.

Now for me the problem is temporarily solved, because I understand
the source of the problem, I have a workaround (pli1_...), and I hope
that the compiler people at my customers' site will send the problem to IBM.

Thank you all, kind regards

Bernd





Am 28.03.2014 03:53, schrieb Bernd Oppolzer:
That looks good and indeed more naturally to me,
I will give it a try ... tomorrow.

Thank you.

Bernd


Am 28.03.2014 00:44, schrieb Charles Mills:
I wonder, what if the OP reversed the casting and instead coded

if ( ptr == (void *)0xff000000 ) ...

Is that legal? (Can you cast a constant to a void* ? My MS VS C++ just let
me do it.) Would that work?

Charles

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN




----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN

Reply via email to