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.