
On 2010-02-15 17:17:57 -0000, John Maddock wrote:
The reason is that mpfr.h supports systems with and without intmax_t (so that it does not force <stdint.h> inclusion), thus it must have a way to determine when intmax_t is available, without requiring the user to do anything else than including <stdint.h> first. So, it has several heuristics, one of them being the test of the existence of INTMAX_C and UINTMAX_C. Indeed, in C, which does not have namespaces, it is rather intuitive that the existence of INTMAX_C and UINTMAX_C implies that the corresponding types intmax_t and uintmax_t are available. However, in C++ with Boost, intmax_t and uintmax_t are not necessarily available (in the global namespace).
Hmm, how can you use INTMAX_C to check for the existance of stdint.h when INTMAX_C is *defined in stdint.h*.
Perhaps I wasn't clear enough: if the user wants to use intmax_t, he needs to make it available explicitly by including <stdint.h> before mpfr.h (see below). Then INTMAX_C gets defined (in C).
Note also that historically C++ systems have not defined INTMAX_C when including stdint.h (or any other header) unless a specific "magic macro" is defined (__STDC_CONSTANT_MACROS).
Yes, this is documented in the MPFR manual, as some users use a C++ compiler even to compile C programs. So, for better portability, a user should do: #if defined(__cplusplus) # define __STDC_CONSTANT_MACROS #endif #include <stdint.h> #include <mpfr.h> That's at least for C programs. Now, specifically for C++ programs...
Which brings us on to C++0x and the next C++ std. In there INTMAX_C is always defined after including <cstdint>, but there is no intmax_t in global namespace (only namespace std) - it's this behaviour that Boost's stdint.hpp is trying to emulate. We're also not alone in this - for example ICU will define some of the INT#_C macros if they're not already supplied. And finally... the behaviour was introduced in response to user requests/bug reports, so I don't think we'll change, sorry!
I don't think there are much problems with the next C++ standard. We don't know very much about users who use MPFR with their C++ programs, but I think that in practice, such users who want the stdint types always include <stdint.h> as documented in the MPFR manual, and in this case, intmax_t is available in the global namespace, according to <http://en.wikipedia.org/wiki/Stdint.h>. The problem is with systems that don't have a <stdint.h> header. On such systems at least, Boost can now break MPFR. But I think that if mpfr.h is included *before* C++/Boost-related headers, then everything should work fine, because when the MPFR test on INTMAX_C occurs, this macro hasn't been defined yet by Boost or other C++-related headers.
BTW Doesn't mpfr already use an autoconf script for configuration?
The autoconf script is used to build the MPFR library, not for using the MPFR library in external programs. Moreover the mpfr.h file is the same for all platforms (it is not generated[*]). That's why MPFR functions that have (u)intmax_t as an argument or return type should be declared in mpfr.h only if (u)intmax_t is available. [*] We probably wouldn't like to do that anyway, as the conventional tools are not designed for architecture-dependent headers files. -- Vincent Lefèvre <vincent@vinc17.net> - Web: <http://www.vinc17.net/> 100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/> Work: CR INRIA - computer arithmetic / Arénaire project (LIP, ENS-Lyon)