Bug 53870

Summary: C++ undeclares standard math functions like isinf()
Product: Base System Reporter: Michael van Elst <mlelstv>
Component: binAssignee: David Schultz <das>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 5.1-CURRENT   
Hardware: Any   
OS: Any   

Description Michael van Elst 2003-06-28 11:40:11 UTC
The following C++ program does not compile on FreeBSD5.*

#include <cmath>
void foo()
{
    double d;
    isinf(d);
}

The error message is:

c.cc: In function `void foo()':
c.cc:5: error: `isinf' undeclared (first use this function)
c.cc:5: error: (Each undeclared identifier is reported only once for each 
   function it appears in.)

This is caused by isinf() being a macro defined in math.h which is
then undef'd in the cmath header. The compiler _should_ then see the
underlying function implementation instead of the macro.

The same is true for some other functions declared in the near vicinity:

isinf()
isnan()
signbit()

and some others like fpclassify() and isfinite(). The latter however
do not exists as functions in libc.

The error appeared with the introduction of GCC3.3.

Fix: 

Add prototypes for isinf(), isnan(), signbit() functions to math.h.
Add function implementations for the other functions that are only
macros.
How-To-Repeat: See above
Comment 1 Artem 'Zazoobr' Ignatjev 2003-06-28 11:54:22 UTC
Michael van Elst wrote:
> >Description:
> The following C++ program does not compile on FreeBSD5.*
> 
> #include <cmath>
Add:
using namespace std;
> void foo()
> {
>     double d;
>     isinf(d);
> }
>
Comment 2 Michael van Elst 2003-06-28 12:10:08 UTC
On Sat, Jun 28, 2003, Artem 'Zazoobr' Ignatjev wrote:

> > #include <cmath>
> Add:
> using namespace std;

Thanks, this helps. Can you explain why this is necessary for isinf()
but not for functions like sin() ?

The only difference seems to be that isinf() happens to implemented as
a macro (it used to be a function in FreeBSD4).

Greetings,
-- 
    ,eM""=.            a"-.                         Michael van Elst
   dWWMWM" -          :GM==;                        mlelstv@dev.de.cw.net
  :WWMWMw=--.          "W='  cable & wireless
   9WWMm==-.
    "-Wmw-"  CABLE & WIRELESS
Comment 3 Bruce M Simpson freebsd_committer freebsd_triage 2004-06-14 22:22:26 UTC
State Changed
From-To: open->analyzed

Please see the following URL: 
http://gcc.gnu.org/ml/libstdc++/2003-04/msg00119.html 

As per above the following hack will work: 

#include <cmath> 
void foo() 
{ 
using namespace std; /* XXX */ 
double d; 
isinf(d); 
} 


Comment 4 Bruce M Simpson freebsd_committer freebsd_triage 2004-06-14 22:22:26 UTC
Responsible Changed
From-To: freebsd-bugs->kan

das@ has been handling some of this, so assign to him.
Comment 5 Bruce M Simpson freebsd_committer freebsd_triage 2004-06-15 23:33:25 UTC
Responsible Changed
From-To: kan->das

Doh, my bad, meant das, not kan.
Comment 6 David Schultz freebsd_committer freebsd_triage 2007-01-03 05:29:49 UTC
State Changed
From-To: analyzed->closed

First of all, if you include <cmath> (or any other new C++ header 
file) as opposed to <math.h>, the C++ standard says that all the 
declared symbols from the header file are placed in namespace std. 
The fact that your example program compiles on some systems without 
a `using namespace std;' line is a bug.  However, it seems that the 
version of gcc in FreeBSD 6.x re-introduces this bug for backwards 
compatiblity, so your program compiles once again.