Bill Allombert on Wed, 16 Sep 2009 00:44:10 +0200

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: Problems with has_log2.c and has_exp2.c

On Mon, Sep 14, 2009 at 11:17:40AM +0200, Jeroen Demeyer wrote:
> Hello all,
> I had a problem compiling sage-4.1.1 with gcc-4.5.0 and it could be  
> traced back to a problem in PARI's Configure programs has_log2.c and  
> has_exp2.c (which are the same for pari-2.3.3 and pari-SVN).
> Now the long story of why:
> On my system, the functions log2() and exp2() only exist when compiling  
> C99 or C++ code.  Not C89, which is still the default for gcc:
> $ gcc -lm -o has_exp2 has_exp2.c
> has_exp2.c:2: error: 'exp2' undeclared here (not in a function)
> $ gcc -std=c99 -lm -o has_exp2 has_exp2.c
> has_exp2.c:2: warning: initialization from incompatible pointer type
> has_exp2.c: In function 'main':
> has_exp2.c:3: warning: comparison of distinct pointer types lacks a cast
> $ g++ -lm -o has_exp2 has_exp2.c
> has_exp2.c:2: error: invalid conversion from 'double (*)(double)throw  
> ()' to 'char (*)()'
> has_exp2.c: In function 'int main()':
> has_exp2.c:3: error: comparison between distinct pointer types 'char  
> (*)()' and 'double (*)(double)throw ()' lacks a cast

As far as I see, the issue is two-fold:
1) The file has_exp2.c is not valid in C++, hence this cause Configure
to omit HAS_EXP2. The file has_exp2.c would be better written as:
#include <math.h>
double (*f)(double) = exp2;
int main(){ return f != exp2; }
(since the prototype is part of the standard)

2) For some reason src/paricom.h has
#ifndef HAS_EXP2
#  undef exp2
#  ifdef __cplusplus
     inline double exp2(double x) {return exp(x*LOG2);}
#  else
#    define exp2(x) (exp((double)(x)*LOG2))
#  endif

I suspect the reason for the ifdef __cplusplus was because
inline is not valid in C89. However it is wrong to have different headers
for C and C++, and cause the problem here.

I fixed both 1) and 2) in revision 11920. It work with g++ 4.3, I hope
it also work with g++ 4.5.