Warnings in GMP.H, and potentially more serious problem
delta trinity
deltatrinity at hotmail.com
Sat May 15 15:24:32 CEST 2004
Hello
Well, this is to follow the issue with warnings in GMP.H 4.1.3
Note that looking at the code, I found a possible serious problem which
could result in wrong value returned to mpz_get_ui.
Setup
-----
x86 platform (P4)
Borland C++ Builder 6.0
GMP 4.1.3 shared library compiled with MinGW (gcc version 3.2.3).
./configure --disable-static --enable-shared -host=i386-pc-mingw32 (if I
compile for other x86 platforms, the problem is the same, the generated
gmp.h is the same).
Problem
-----
When compiling C++ applications (standard 'c' applications doesn't seem to
cause the warnings) using GMP.H 4.1.3 in Borland C++ Builder 6, I get
[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.
In the header, this is at (marked by ====HERE====):
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];
if (__GMP_ULONG_MAX <= GMP_NUMB_MASK) ====HERE====
return __gmp_l & (-(mp_limb_t) (__gmp_n != 0)); ====HERE====
#if GMP_NAIL_BITS != 0 /* redundant #if, shuts up compiler warnings */
else /* happens for nails, but not if LONG_LONG_LIMB */
{ /* assume two limbs are enough to fill an ulong */
__gmp_n = __GMP_ABS (__gmp_n);
if (__gmp_n <= 1)
return __gmp_l & (-(mp_limb_t) (__gmp_n != 0));
else
return __gmp_l + (__gmp_p[1] << GMP_NUMB_BITS);
}
#endif
}
The first warning is because two constants are used in the equation (in
fact, 2 defines). Equivalent to (in this case)
if (32 <= 32)
The second warning is due to negating an unsigned value.
Possible flaw
-----
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. Is 'true' defined as any non-zero value? I'm not sure. But if so,
this could evaluate to 0xFFFFFFFF. The expression would then evaluate to:
return __gmp_l & (-(mp_limb_t) (0xFFFFFFFF)); /* (-1) */
return __gmp_l & (1);
So, it is questionable if the current gmp.h work for every compilers in its
current state. Some tests should be made regarding that.
With my compiler though, this doesn't cause problems. The (__gmp_n != 0)
actually compile to
cmp dword ptr [ebp-0x2c],0x00
setnz al
and eax,0x01
Which set eax to either 0 or 1.
note
-----
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++.
Regards
Eric
_________________________________________________________________
Express yourself with the new version of MSN Messenger! Download today -
it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/
More information about the gmp-bugs
mailing list