I think we should test if LLONG_MAX is defined. This actually doesn't
tell us if long long exists, but tells us if long long exists AND the
system long long's are fully c99 compliant.

Then if LLONG_MAX is not defined but MAXINT_MAX is defined and not
equal to LONG_MAX, then we should define maxint_t function.

I'll try this and see if it works. I think this is what is causing the
bug on the ia64 machine with gcc 4.1.2.

Bill.

On 12 October 2012 20:10, Bill Hart <goodwillh...@googlemail.com> wrote:
> 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