Bug 14608 - <iostream.h> nukes isfinite macro from <math.h>
<iostream.h> nukes isfinite macro from <math.h>
Status: NEW
Product: gcc
Classification: Unclassified
Component: libstdc++
3.4.0
: P2 normal
: ---
Assigned To: Not yet assigned to anyone
: documentation
: 48406 (view as bug list)
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2004-03-16 18:23 UTC by Zack Weinberg
Modified: 2014-11-15 12:30 UTC (History)
3 users (show)

See Also:
Host:
Target: ia64-hp-hpux11.23
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-12-10 05:36:06


Attachments
original testcase (161 bytes, text/plain)
2004-03-16 18:23 UTC, Zack Weinberg
Details
workaround - only for 3.3.x (379 bytes, text/plain)
2004-03-16 18:24 UTC, Zack Weinberg
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Zack Weinberg 2004-03-16 18:23:08 UTC
I will attach two test cases to this bug.  The first test case was provided to
me by a customer; it is a cut-down version of a larger piece of code that did
need both <math.h> and <iostream.h>.  The observed problem is that if both these
headers are included (in either order) in the same translation unit, the
isfinite macro (part of C99) is not available to subsequent code.  If only
<math.h> is included, then isfinite is available.

The second test case is the workaround that I found for GCC 3.3.3.  It does not
work with GCC 3.4, even with the obvious s/GLIBCPP/GLIBCXX/.

It should be noted that HPUX's libc does not implement all of C99, but it *does*
provide all of the C99 math functions - but isfinite() and friends are only
macros (which is allowed by C99).  I don't know what the C++ standard specifies
in this area but it seems to me that QoI dictates that C++ programs be able to
use all the system-provided library facilities.
Comment 1 Zack Weinberg 2004-03-16 18:23:44 UTC
Created attachment 5930 [details]
original testcase
Comment 2 Zack Weinberg 2004-03-16 18:24:20 UTC
Created attachment 5931 [details]
workaround - only for 3.3.x
Comment 3 Andrew Pinski 2004-03-16 19:15:30 UTC
Confirmed, it also shows up on powerpc-apple-darwin7.2.0 also.
Comment 4 Gabriel Dos Reis 2004-03-16 19:52:00 UTC
Subject: Re:  New: <iostream.h> nukes isfinite macro from <math.h>



Short answer for this PR:  Use -D_GLIBCXX_USE_C99_MATH if you want to
retain C99 random bits consistently.


Longer answer:

"zack at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes:

| I will attach two test cases to this bug.  The first test case was
| provided to me by a customer; it is a cut-down version of a larger
| piece of code that did need both <math.h> and <iostream.h>.  The
| observed problem is that if both these headers are included (in
| either order) in the same translation unit, the isfinite macro (part
| of C99) is not available to subsequent code.  If only <math.h> is
| included, then isfinite is available. 

The bug is that isfinite() is at all available *as macro*, when
<math.h> is included.  But, that is a general problem in that we don't
have control over <math.h> and so we don't remove sneaky macros as we
should all the time. 

First of all, C++ explicitly permits any standard header that is not
inherited from C to include any other standard header -- that is
hardly avoidable.  <iostream.h> is not a standard header but is
provided as a courtesy (see appendix D of the C++ standard) and is, in
fact, an inclusion of <iostream> followed by a series of
using-declarations -- as is done for C inherited headers <xxx.h> as
mandated by the C++ standard.  <iostream> (transively) includes
<cmath> for whatever reasons.  <cmath> turn functional macros into
functions, and by default provides only C90 functions.

However, you may specify -D_GLIBCXX_USE_C00_MATH if you want to retain
C99 random bits.

| The second test case is the workaround that I found for GCC 3.3.3.
| It does not work with GCC 3.4, even with the obvious s/GLIBCPP/GLIBCXX/.
| 
| It should be noted that HPUX's libc does not implement all of C99,
| but it *does* provide all of the C99 math functions - but isfinite()
| and friends are only macros (which is allowed by C99).  I don't know
| what the C++ standard specifies in this area but it seems to me that
| QoI dictates that C++ programs be able to use all the
| system-provided library facilities. 

Discussing "dictated" behaviour without looking at what the C++
standard says is a good recipe for frustration and waste of time.

The C++ committee is considering adding  -- to the first Technical
Report (not a standard in its strict sense) -- modified versions of
the myriad of functions C99 added to C90.  PJ. Plauger made a report
early in 2002 and followed up with

  http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1503.txt

and more corrections in subsequent mailings.  
Turning C99 sneaky functional macros into plain functions are general
requirements of C++ and also recommended in the above proposal.
The implementation of V3 is in adequation with those recommandations.

I propose to close this PR.  The only bug here is that we don't remove
macros consistently, but that is a known problem we don't have a
solution for right now.

-- Gaby
Comment 5 Gabriel Dos Reis 2004-03-16 19:53:16 UTC
Subject: Re:  <iostream.h> nukes isfinite macro from <math.h>

"pinskia at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes:

| Confirmed, it also shows up on powerpc-apple-darwin7.2.0 also.

Try with -D_GLIBCXX_USE_C99_MATH.

-- Gaby
Comment 6 Zack Weinberg 2004-03-16 21:08:28 UTC
Subject: Re:  <iostream.h> nukes isfinite macro from
 <math.h>


I think the person who reported this bug to me would be fine with
std::isfinite() being reliably available (possibly with a magic macro
to turn it on) in C++ on HP-UX.

zw
Comment 7 Zack Weinberg 2004-03-17 09:50:21 UTC
Subject: (PR 14608) [Dennis Handly] RE: Problem with GCC/G++ on HP-UX -
 v3.3.2prerelease - iostream/math.h


Further comments from the customer ...

>From: "Zack Weinberg" <zack@codesourcery.com>
>Dennis is not far off.  What's happening is that <iostream> includes
><cmath>.  <cmath> includes <math.h> and then #undefs a bunch of macros
>that a strict reading of C++98 disallows, including "isfinite".

Strict reading of C++98 would also disallow you undefing user macros
just to make the namespace clean.

I.e. suppose the user defined isfinite and you undefed it.
And if _HPUX_SOURCE is defined, (to get isfinite) you shouldn't undef it.

Unless you are very clever and check the definition before you include
<cmath> and only undef it if it wasn't defined.

Basically HP-UX never has defined a C++ clean namespace and unless
you can get the HP-UX people involved, you doing it by yourself is a
lost cause.
Comment 8 Gabriel Dos Reis 2004-03-17 10:24:32 UTC
Subject: Re:  <iostream.h> nukes isfinite macro from <math.h>

"zack at codesourcery dot com" <gcc-bugzilla@gcc.gnu.org> writes:

| Further comments from the customer ...
| 
| >From: "Zack Weinberg" <zack@codesourcery.com>
| >Dennis is not far off.  What's happening is that <iostream> includes
| ><cmath>.  <cmath> includes <math.h> and then #undefs a bunch of macros
| >that a strict reading of C++98 disallows, including "isfinite".
| 
| Strict reading of C++98 would also disallow you undefing user macros
| just to make the namespace clean.

Strict reading of C++98 requires that the following program compile,
if it fails then it is V3 error:

    #include <cmath>

     namespace foo {
        void isfinite(int) { return 0; } 
     }

-- Gaby
Comment 9 Benjamin Kosnik 2009-01-27 20:49:48 UTC
Looks to me like the flipside of libstdc++/7439. More broadly speaking, C99 macros vs. C++98/0x. The current status on this issue is:

For 4.1/4.2/4.3/trunk, C99 macros should be visible with 
  1) -std=gnu99/c99 in "C" code (platform-specific if this is guarded: linux is) 
  2) with _GLIBCXX_USE_C99_MATH defined for c++98/0x, macros are undefined and templates scoped in namespace std:: are visible. The macro _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC can be defined to suppress this, and define the macros.

This seems like standards-conformant behaviour is possible with the right combination of defines. Sadly, this is not documented, and clearly need to be. With documentation to explain this, I think this bug can be closed.

I am adding the keyword documentation to this bug and will take care of it in the next documentation sweep.
Comment 10 Paolo Carlini 2011-04-02 10:46:32 UTC
*** Bug 48406 has been marked as a duplicate of this bug. ***
Comment 11 Paolo Carlini 2011-04-02 12:01:33 UTC
In fact, as noticed in 48406, adding back at the end definitions to the global namespace appears to basically work, we have only to be careful about the return type (int or bool in the global namespace? In std::, for C++0x we want bool. It seems to me that, in C++0x mode at least, bool would be more consistent for the global namespace too, but then including or not including <cmath> after <math.h> makes a difference, weird) and other details, like, for example, on gnu-linux, <math.h> appears to define isinf and isnan as functions in the global namespace, I'm, afraid this kind of target dependent vagaries in <math.h> have to be dealt with on a case by case way, maybe with some configury :(
Comment 12 Francois-Xavier Coudert 2014-11-15 12:30:10 UTC
I don't know what's the status of this on hpux, but on darwin it got fixed at some point.