Warnings in GMP.H, and potentially more serious problem

jfoug at cox.net jfoug at cox.net
Sun Jul 4 19:11:27 CEST 2004


The easiest "fix" to this problem is to change the line (2 lines actually in different #defines) from

return __gmp_l & (-(mp_limb_t) (__gmp_n != 0));

to

return __gmp_l & (~((mp_limb_t) (__gmp_n != 0)));


I am not sure if the code you listed below:    return (__gmp_n != 0 ? __gmp_l : 0);  would cause conditional execution paths or not, but I image that it does.  The code I listed above should not, and if the (__gmp_n != 0) does, then it can be changed to !!_gmp_n  as in:

return __gmp_l & (~((mp_limb_t)!!__gmp_n));

Jim.

----- Orignal messages -------

"delta trinity" <deltatrinity at hotmail.com> writes:
>
> [C++ Warning] gmp.h(1595): W8008 Condition is always true
> [C++ Warning] gmp.h(1596): W8041 Negating unsigned value
>
> Those are only warnings, and does not cause the compilation to fail.

They're also a bit over zealous really, but we should be able to avoid
them.  I'm looking at something like the following.

unsigned long
mpz_get_ui (mpz_srcptr __gmp_z) __GMP_NOTHROW
{
  mp_ptr __gmp_p = __gmp_z->_mp_d;
  mp_size_t __gmp_n = __gmp_z->_mp_size;
  mp_limb_t __gmp_l = __gmp_p[0];
  /* This is a "#if" rather than a plain "if" so as to avoid gcc warnings
     about "<< GMP_NUMB_BITS" exceeding the type size, and to avoid Borland
     C++ 6.0 warnings about condition always true for something like
     "__GMP_ULONG_MAX < GMP_NUMB_MASK".  */
#if GMP_NAIL_BITS == 0 || defined (_LONG_LONG_LIMB)
  /* limb==long and no nails, or limb==longlong, one limb is enough */
  return (__gmp_n != 0 ? __gmp_l : 0);
#else
  /* limb==long and nails, need two limbs when available */
  __gmp_n = __GMP_ABS (__gmp_n);
  if (__gmp_n <= 1)
    return (__gmp_n != 0 ? __gmp_l : 0);
  else
    return __gmp_l + (__gmp_p[1] << GMP_NUMB_BITS);
#endif
}


> Looking at the code, at the second warning, could (__gmp_n != 0) give
> problems if a compiler decide to evaluate the expression to anything
> other than 1.

No, the relational operators always give 1 or 0.

> The warnings themself are seen when I compile C++ console application.
> I tried compiling a C console application and they didn't show.
> Probably the compiler use two different core for C and C++.

Or it's just the nature of c++ to be pedantic, g++ is pickier than gcc
too.




More information about the gmp-bugs mailing list