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