Reputation: 101
I have found the large-precision code of MPFR C++ to be very useful, and have used it successfully in the past. Recently, while developing a new app, I encountered an enormous number of compiler errors in their header code (mpreal.h). I have identified the cause of all these errors: the the use of a name both in a typedef and as the name of a function, coupled with an unintuitive result of a macro. The relevant macro was in the mpfr package, and occurred between mpfr 4.0.2-5 and 4.1.0-6. I am using the latest version of mpreal.h (version 3.6.8), but other earlier versions behave the same.
The compiler errors vary somewhat, but the following is typical:
In file included from mpreal.h:125:
mpreal.h:624:32: error: no matching function for call to ‘mpfr::mpreal::mpfr_srcptr(const __mpfr_struct*&)’
624 | mpfr_init2(mpfr_ptr(), mpfr_get_prec(u));
| ^~~~~~~~~~~~~
mpreal.h:324:19: note: candidate: ‘const __mpfr_struct* mpfr::mpreal::mpfr_srcptr() const’
324 | ::mpfr_srcptr mpfr_srcptr() const;
| ^~~~~~~~~~~
mpreal.h:324:19: note: candidate expects 0 arguments, 1 provided
The relevant lines of code (int addition to the above) are:
mpreal.h:125 #include <mpfr>
mpfr.h:866 #define mpfr_get_prec(_x) MPFR_VALUE_OF(MPFR_SRCPTR(_x)->_mpfr_prec)
mpfr.h:845 #define MPFR_VALUE_OF(x) (0 ? (x) : (x))
mpfr.h:847 #define MPFR_SRCPTR(x) ((mpfr_srcptr) (0 ? (x) : (mpfr_srcptr) (x)))
The problem seems to be in the macro of line 847. The (mpfr_srcptr) (x) appearing in MPFR_SRCPTR(x) is meant to be a type-cast of x to the type mpfr_srcptr, but is being interpreted to mean a call to mpfr_srcptr() with argument x. Outside of a macro, gcc can tell the difference between (mpfr_srcptr)(x) and mpfr_srcptr(x), but the macro is apparently ignoring the parentheses. Can anyone explain this macro behavior? I know that gcc has a huge number of switches to control almost everything, but is there an option somewhere that would affect the interpretation of parentheses in macros?
I suppose that this behavior could be unique to my system, but I find that hard to believe. But I also find it hard to believe that such a bug has gone unnoticed by the rest of the community; I found no suggestion of any problem either on the website or on github, to which the project has recently been transferred.
Upvotes: 2
Views: 228
Reputation: 101
The macro SRCPTR is not ignoring parentheses as I originally thought; the behavior is explained by the difference in scopes. The SRCPTR macro, while occurring within the mpfr coding at global scope, is actually being called from mpreal's scope. Since mpreal has redefined srcptr as a function, that definition is the only one used when SRCPTR is executed from mpreal. (SRCPTR, being a macro, has no scope.) When mpfr's functions are called from mpreal, the functions operate with the global scope, and the SRCPTR macro invoked there would therefore use the global definition.
Upvotes: 1