Prototype for "double pow(double,int)"

Dear all:

I am having trouble with the protopoy of “pow” in C++.
I am asking suggestion to avoid to manualy change a system
include file. With the change reported below I was able to succesfully compile my code. However since this is a multiplatform code
I would like to advoid such local changes.

Any suggestions?

Details below:

In particular I had to manualy add this prototype in: math.h

master:/opt/cluster # diff /opt/cluster/pgi/linux86-64/5.2/include/math.h  /opt/cluster/pgi/linux86-64/5.2/include/math.h.orig -p
*** /opt/cluster/pgi/linux86-64/5.2/include/math.h      Wed Dec 22 12:01:51 2004
--- /opt/cluster/pgi/linux86-64/5.2/include/math.h.orig Wed Dec 22 11:44:17 2004
*************** double  exp (double x);
*** 126,132 ****
  double        log (double x);
  double        log10 (double x);
  double        pow (double x, double y);
- double        pow (double x, int n);
  double        sqrt (double x);
  double        ceil (double x);
  double        floor (double x);
--- 126,131 ----
*************** double log(double);
*** 211,217 ****
  double log10(double);
  double exp(double);
  double pow(double,double);
- double pow(double,int);
  }
  
  #endif
--- 210,215 ----

The headr part of the code where the error was generate
is:

#include <assert.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>

#include <iostream>
#include <sstream>
#include <vector>

#include "cctk.h"
#include "cctk_Parameters.h"

#include "util_ErrorCodes.h"
#include "util_Table.h"

#include "bbox.hh"
#include "defs.hh"
#include "dist.hh"
#include "ggf.hh"
#include "gh.hh"
#include "vect.hh"

#include "carpet.hh"

extern "C" {
  static const char* rcsid = "$Header: /home/cvs/carpet/Carpet/Carpet/src/SetupGH.cc,v 1.85 2004/08/07 20:07:27 schnetter Exp $";
CCTK_FILEVERSION(Carpet_Carpet_SetupGH_cc)
}
...

The original error I got was:

cd /home/albert2/bgiacoma/Cactus/configs/test_carpet/scratch; 
pgCC -Drestrict= --no_using_std --instantiate=used -fast -O3 \
  -Minfo -Mneginfo -Mvect=assoc -c \
  -o $current_wd/SetupGH.cc.o $current_wd/SetupGH.cc \
  -I"/opt/cluster/hdf5/include" \
  .......(mo include directive)....  
  -DTHORN_IS_Carpet -DCCODE \
  "/home/albert2/bgiacoma/Cactus/configs/test_carpet/build/Carpet/SetupGH.cc", line 285: warning:
          statement is unreachable
      return op_error;
      ^
 
"/home/albert2/bgiacoma/Cactus/configs/test_carpet/build/Carpet/SetupGH.cc", line 424: error:
          more than one instance of overloaded function "pow" matches the
          argument list:
            function "pow(double, double)"
            function "std::pow(const std::complex<long double> &, int)"
            function "std::pow(const double &, const std::complex<double> &)"
            function "std::pow(const std::complex<double> &, int)"
            function "std::pow(const std::complex<float> &, int)"
            argument types are: (double, int)
          = base_spacing * pow (CCTK_REAL(convergence_factor), basemglevel);
                           ^
 
"/home/albert2/bgiacoma/Cactus/arrangements/Carpet/CarpetLib/src/vect.hh", line
563: error:
          more than one instance of overloaded function "pow" matches the
          argument list:
            function "pow(double, double)"
            function "std::pow(const std::complex<long double> &, int)"
            function "std::pow(const double &, const std::complex<double> &)"
            function "std::pow(const std::complex<double> &, int)"
            function "std::pow(const std::complex<float> &, int)"
            argument types are: (const double, const int)
    for (int d=0; d<D; ++d) r[d]=pow(a[d],b[d]);
                                 ^
          detected during instantiation of "vect<T, DD> pow(const vect<T, DD>
                    &, const vect<U, D> &) [with T=double, U=int, D=3]"

[/list]

Depietri -

C++ is a tightly typed language. It looks like you
are passing an integer value as the second parameter,
when pow expects a double. The change to math.h is not
the portable solution. Since you did not include
a small test case, I can only make the suggestion
that you change the line

for (int d=0; d<D; ++d) r[d]=pow(a[d],b[d]);

to

for (int d=0; d<D; ++d) r[d]=pow(a[d],(double) b[d]);

and see if that works. The second parameter must be of type
double.

Dear Caruso:

I known of this tricks. I was wondering the reason why I was not getting
the correct call to pow(double,int). The code I am having the problem
is part of a gig 100000+ line of codes multiplatform application and
we whould like to advoid different version for different compiler.

Looking in Strouststrup “The C++ Programming language, Special edition”
at pag. 660 section 22.3 it is mentioned that the header of
and <math.h> should include a prototype to “double pow(double,int)”
and there are very good reason do be that way.

It is well known that pow(double,double) is a very difficult function to
be implemented and should be advoid, when possible.

In fact in the sample code (an extract) I submited there is the
include line

#include <math.h>

Making a call to double pow(double,double) instead of
double pow(double,double) it is not a good idea since is usualy
slower and less accurate. In fact in the library there are two
version of this function.

My impression was that I was getting the wrong “math.h” included and
I was wondering why.

If you can be sure that your libc.a contains a function declared as pow(doube, int)
then your original fix is fine. We do not provide libc.a , and only provide
a math.h to deal with some portablility and C++ issues. Our math.h uses an
include_next directive to include the original system file. -Deb Caruso