Whoah, we have some major issues here.

mpirxx.h uses HAVE_LONG_LONG. But this is defined in MPIR's internal
config.h, which is no use, as the end user will not have included
this.

Moreover, I can't find where stdint.h is being included in mpirxx.h. I
think it must be designed so that only when it is included do intmax_t
functions get defined.

But I still don't think that these functions should *ever* need
defining. Either an intmax_t is a long or it is a long long on all
platforms we support. So if the long long function actually worked (it
never will for the user), then the intmax_t function is never needed.

Bill.

On 12 October 2012 19:24, Bill Hart <goodwillh...@googlemail.com> wrote:
> Damn, I am wrong about the last bit. You can't use sizeof in
> preprocessor directives!
>
> But now I am looking at this code and wondering if it is even
> necessary. When do we expect intmax_t to not be either long or long
> long. And we have code for both of the above already.
>
> Bill.
>
> On 12 October 2012 18:53, Bill Hart <goodwillh...@googlemail.com> wrote:
>> I think I have essentially gotten to the bottom of this bug. And it is
>> pretty subtle indeed!
>>
>> The issue is nominative versus structural typing. Consider the
>> following two structs:
>>
>> struct mystruct1
>> {
>>    int d;
>>    double t;
>> }
>>
>> struct mystruct2
>> {
>>    int d;
>>    double t;
>> }
>>
>> Structurally, these are the same type as they contain the same fields
>> (in the same order -- this is important for C). But the names of the
>> structs are different. Thus nominatively they are different.
>>
>> Now C/C++ are by and large nominatively typed. Structs with different
>> names are different for the purpose of type checking.
>>
>> However, there are some exceptions. The template system in C++ is
>> structurally typed. You can instantiate templates with differently
>> named, but structurally identical types without issue, so long as the
>> implementations don't conflict.
>>
>> And then there is typedef. This actually doesn't create a new type for
>> the purposes of type checking. It in fact only creates a type name
>> alias. The type is still considered to be the same for type checking
>> purposes.
>>
>> Now if you look in stdint.h you find that on the system in question,
>> intmax_t is typedef'd to be a long. Thus intmax_t and long are the
>> *same* type on that system. Thus it is invalid to define the function
>> for intmax_t and for long with different implementations. So the
>> compiler is correct to reject this code.
>>
>> Unfortunately, I don't know of a way of comparing two types with
>> preprocessor macros to see if they are the same. But we can compare
>> their sizes with sizeof. It turns out that sizeof is actually a macro,
>> not a function, and so can be compared at compile time. If
>> sizeof(intmax_t) == sizeof(long) then we shouldn't define the second
>> version of the function. The function will still accept an intmax_t
>> because that is the same type as a long.
>>
>> I also found at least one reference which says that intmax_t is
>> *always* a typedef to an existing integral type. At least in C90 the
>> type must be an ordinary integer type, but from C99 onwards it can be
>> an extended integer type (so could conceivably be a uint128_t on a 64
>> bit machine). I'm not sure if we are still using C90 or whether we are
>> using gnu99. And I've no idea what the gnu "standard" says anyway. But
>> at least the fix I suggest should work for quite a few machines. We
>> might have to make further changes if we start running into problems
>> with extended types. I know the Apple GCC does all sorts of unusual
>> things when it comes to standards, so who knows.
>>
>> I will check in this fix to the repo momentarily.
>>
>> Bill.
>>
>> On 11 October 2012 16:01, Bill Hart <goodwillh...@googlemail.com> wrote:
>>> On 7 October 2012 04:10, leif <not.rea...@online.de> wrote:
>>>
>>> <SNIP>
>>>
>>>> On Linux IA64 (SLES 10, Itanium) in contrast, I got the following failures:
>>>>
>>>> With the (fairly old) "native" GCC 4.1.2, building the testsuite fails:
>>>>
>>>> make[4]: Entering directory
>>>> `/home/leif/src/mpir-2.6.0-alpha1-build.iras-gcc-4.1.2/tests/cxx'
>>>> g++ -DHAVE_CONFIG_H -I. -I../../../mpir-2.6.0-alpha1/tests/cxx -I../..
>>>> -I../../../mpir-2.6.0-alpha1 -I../../../mpir-2.6.0-alpha1/tests    -O2 -c 
>>>> -o
>>>> t-assign.o ../../../mpir-2.6.0-alpha1/tests/cxx/t-assign.cc
>>>> ../../../mpir-2.6.0-alpha1/mpirxx.h:1587: error: ‘__gmp_expr<__mpz_struct
>>>> [1], __mpz_struct [1]>::__gmp_expr(intmax_t)’ cannot be overloaded
>>>> ../../../mpir-2.6.0-alpha1/mpirxx.h:1578: error: with
>>>> ‘__gmp_expr<__mpz_struct [1], __mpz_struct [1]>::__gmp_expr(long int)’
>>>> ../../../mpir-2.6.0-alpha1/mpirxx.h:1588: error: ‘__gmp_expr<__mpz_struct
>>>> [1], __mpz_struct [1]>::__gmp_expr(uintmax_t)’ cannot be overloaded
>>>> ../../../mpir-2.6.0-alpha1/mpirxx.h:1579: error: with
>>>> ‘__gmp_expr<__mpz_struct [1], __mpz_struct [1]>::__gmp_expr(long unsigned
>>>> int)’
>>>> ../../../mpir-2.6.0-alpha1/mpirxx.h:1656: error: ‘__gmp_expr<__mpz_struct
>>>> [1], __mpz_struct [1]>& __gmp_expr<__mpz_struct [1], __mpz_struct
>>>> [1]>::operator=(intmax_t)’ cannot be overloaded
>>>> ../../../mpir-2.6.0-alpha1/mpirxx.h:1647: error: with
>>>> ‘__gmp_expr<__mpz_struct [1], __mpz_struct [1]>& __gmp_expr<__mpz_struct
>>>> [1], __mpz_struct [1]>::operator=(long int)’
>>>> ../../../mpir-2.6.0-alpha1/mpirxx.h:1657: error: ‘__gmp_expr<__mpz_struct
>>>> [1], __mpz_struct [1]>& __gmp_expr<__mpz_struct [1], __mpz_struct
>>>> [1]>::operator=(uintmax_t)’ cannot be overloaded
>>>> ../../../mpir-2.6.0-alpha1/mpirxx.h:1648: error: with
>>>> ‘__gmp_expr<__mpz_struct [1], __mpz_struct [1]>& __gmp_expr<__mpz_struct
>>>> [1], __mpz_struct [1]>::operator=(long unsigned int)’
>>>
>>> <SNIP>
>>>
>>> OK, I took a look at this and basically an intmax_t and long int are
>>> the same thing on this machine (as are a uintmax_t and unsigned long
>>> int). Thus it is effectively trying to overload the __gmp_exp function
>>> twice with the same type but different implementations (one calls the
>>> si function, the other calls the sx function).
>>>
>>> This is a problem for which I don't personally know the solution at
>>> present. Any suggestions would be very helpful.
>>>
>>> Bill.

-- 
You received this message because you are subscribed to the Google Groups 
"mpir-devel" group.
To post to this group, send email to mpir-devel@googlegroups.com.
To unsubscribe from this group, send email to 
mpir-devel+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/mpir-devel?hl=en.

Reply via email to