bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 2/2] ffsl, ffsll: new modules


From: Bruno Haible
Subject: Re: [PATCH 2/2] ffsl, ffsll: new modules
Date: Sat, 16 Jul 2011 02:52:08 +0200
User-agent: KMail/1.9.9

Eric Blake wrote:
> +int
> +FUNC (TYPE i)
> +{
> +  int result = 0;
> +  unsigned TYPE j = i;
> +
> +  /* GCC has __builtin_ffs, but it is limited to int.  */
> +  if (!i)
> +    return 0;
> +  while (1)
> +    {
> +      if ((int) j)
> +        return result + ffs (j);
> +      j >>= CHAR_BIT * sizeof (int);
> +      result += CHAR_BIT * sizeof (int);
> +    }
> +}

Here you are relying on the cast from 'unsigned long' to 'int'; its result is
unportable. See ISO C 99 6.3.1.3.(3):
  "[If] the new type is signed and the value cannot be represented in it;
   either the result is implementation-defined or an implementation-defined
   signal is raised."

The fix is to use unsigned integers throughout the operation:


2011-07-15  Bruno Haible  <address@hidden>

        ffsl, ffsll: Avoid unportable behaviour.
        * lib/ffsl.h (FUNC): Use 'unsigned int' instead of 'int'.

--- lib/ffsl.h.orig     Sat Jul 16 02:50:27 2011
+++ lib/ffsl.h  Sat Jul 16 02:47:03 2011
@@ -39,9 +39,9 @@
     return 0;
   while (1)
     {
-      if ((int) j)
-        return result + ffs (j);
-      j >>= CHAR_BIT * sizeof (int);
-      result += CHAR_BIT * sizeof (int);
+      if ((unsigned int) j)
+        return result + ffs ((unsigned int) j);
+      j >>= CHAR_BIT * sizeof (unsigned int);
+      result += CHAR_BIT * sizeof (unsigned int);
     }
 }

-- 
In memoriam Natalya Estemirova <http://en.wikipedia.org/wiki/Natalya_Estemirova>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]