Bug 44611 - Including <math.h> and <cmath> hides ::signbit function
Summary: Including <math.h> and <cmath> hides ::signbit function
Status: RESOLVED DUPLICATE of bug 14608
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.5.0
: P3 minor
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-06-21 14:26 UTC by Adrian Cornish
Modified: 2016-01-08 00:55 UTC (History)
1 user (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Source file (226 bytes, text/plain)
2010-06-21 14:31 UTC, Adrian Cornish
Details
--save-temps output .ii file (64.62 KB, text/plain)
2010-06-21 14:31 UTC, Adrian Cornish
Details
--save-temps output .s file (28 bytes, text/plain)
2010-06-21 14:32 UTC, Adrian Cornish
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Adrian Cornish 2010-06-21 14:26:14 UTC
When both of these files are included - compiler cannot locate c global signbit function.

adrianc@dluadrianc:~/gcc_bug> g++ signbit.cc
signbit.cc: In function 'int main(int, char**)':
signbit.cc:18:42: error: 'signbit' was not declared in this scope

#include <iostream>
#include <math.h>
#include <cmath>

int main(int argc, char *argv[])
{
   float a=12.4234;
   float b=-123.4333;

#ifdef _XOPEN_SOURCE
   std::cout << "_XOPEN_SOURCE=" << _XOPEN_SOURCE << std::endl;
#endif

#ifdef _ISOC99_SOURCE
   std::cout << "_ISOC99_SOURCE is here\n";
#endif

   std::cout << "signbit a=" << signbit(a) << std::endl;
   std::cout << "signbit b=" << signbit(b) << std::endl;

   return 0;
}


adrianc@dluadrianc:~/gcc_bug> gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/i686-pc-linux-gnu/4.5.0/lto-wrapper
Target: i686-pc-linux-gnu
Configured with: ../gcc-4.5.0/configure --enable-__cxa_atexit --enable-languages=c,c++ --enable-threads --with-cpu=core2 --disable-nls --with-arch=i686 --with-mpfr=/usr/local --with-gmp=/usr/local --with-mpc=/usr/local --with-build-time-tools=/usr/local --enable-lto
Thread model: posix
gcc version 4.5.0 (GCC)
Comment 1 Adrian Cornish 2010-06-21 14:31:06 UTC
Created attachment 20963 [details]
Source file
Comment 2 Adrian Cornish 2010-06-21 14:31:38 UTC
Created attachment 20964 [details]
--save-temps output .ii file
Comment 3 Adrian Cornish 2010-06-21 14:32:03 UTC
Created attachment 20965 [details]
--save-temps output .s file
Comment 4 Paolo Carlini 2010-06-21 14:44:47 UTC
I don't think signbit is special: including *any* <c*> header first undefs the names, thus if they are defined as macros in C, you don't see them anymore in the global namespace, only in std::. If, on the other hand, your specific point is one about the C99 classification macros, yes those are enabled by default, can be disabled at library configure time with --disable-c99. In fact the issue whether C99 facilities should be enabled by default in c++98 mode is a very old one, you can find traces of it in bugzilla for sure, and now is definitely *way too old* to change our decision, considering that all of that is standard in c++0x, which is behind the corner.
Comment 5 Jonathan Wakely 2010-06-21 14:52:00 UTC
But should std::signbit be available as ::signbit when <math.h> is included, at least for c++0x mode?

[depr.c.headers]/2 says
"Every C header, each of which has a name of the form name.h, behaves as if each name placed in the standard library namespace by the corresponding cname header is placed within the global namespace scope."

signbit is placed in namespace std by <cmath> which says to me that it should be placed in the global namespace by <math.h>

(I'm still unsure whether the same applies to <stddef.h> and std::nullptr_t)
Comment 6 Paolo Carlini 2010-06-21 15:41:19 UTC
To be honest, I have zero doubts about nullptr_t: nowhere 18.2 hints at providing it in the global namespace, per se.

About signbit, if it's a macro in C it has to be undefined in order to implement the <cmath> facility in c++0x, see 26.8/11. Really, I don't see how the macro and the template can co-exist: "The templates defined in <cmath> replace the C macros with the same names" and the templates are specified in namespace std.

If, on the other hand, we are talking in general about the *.h headers, the basic point of DR456, finally resolved, is that those headers very often come together with the C library, over which many C++ library implementations have ***no control*** today (maybe back in the C++98 times people have some other ideas about the interaction between C and C++ in typical platforms, I don't know) Irrespective of the details of the resolution, that is the very important gist of the resolution: implementors of the C++ library are supposed to not have controls on the internals of the *.h C headers and for sure are not supposed to add in facilities. If, in corner cases (*), that is still not clear enough, maybe (other members of) the LWG can further clarify the matter, but it's clear enough for me ;)

(*) In the past, we had one, that with memchr & co, which has been resolved by Jakub at the C headers level because <cstring> could not be implemented correctly otherwise. At some point I wanted to raise the issue in the LWG, because, missing an ISO clarification, we forced in a glibc + v3 solution which is contrary to the gist of 456.
Comment 7 Jonathan Wakely 2010-06-21 15:56:37 UTC
(In reply to comment #6)
> To be honest, I have zero doubts about nullptr_t: nowhere 18.2 hints at
> providing it in the global namespace, per se.

[depr.c.headers]/3
"The header <stdlib.h> assuredly provides the same declarations and definitions within the global namespace"

Note "the same declarations", not "the subset of declarations defined in the C standard"

> About signbit, if it's a macro in C it has to be undefined in order to
> implement the <cmath> facility in c++0x, see 26.8/11. Really, I don't see how
> the macro and the template can co-exist: "The templates defined in <cmath>
> replace the C macros with the same names" and the templates are specified in
> namespace std.

I agree the macro and template can't co-exist, but the template could be available as both std::signbit and ::signbit, and I think that's required by appendix D.

I agree this isn't ideal, and DR456 tried to help, I don't think DR456 goes far enough in relaxing the requirements on implementations.
Comment 8 Paolo Carlini 2010-06-21 16:02:52 UTC
To be clear: I'm against fiddling with *.h headers, basing on DR456. If you want to do that, for each C library we support, good luck, but I'm not going to help, sorry.

And note that appendix D talks about *the C .h headers*, thus anything you do in the global namespace has to happen via a C *.h header.
Comment 9 Adrian Cornish 2010-06-21 16:07:39 UTC
> I agree the macro and template can't co-exist, but the template could be
> available as both std::signbit and ::signbit, and I think that's required by
> appendix D.

Are these still relevant for c++0x? More so section 5 which says if they are macros in C they must be macros in C++

17.4.1.2 Headers
4. Except as noted in clauses 18 through 27, the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in ISO/IEC 9899:1990 Programming Languages C (Clause 7), or ISO/IEC:1990 Programming Languages—C AMENDMENT 1: C Integrity, (Clause 7), as appropriate,
as if by inclusion. In the C++ Standard Library, however, the declarations and definitions (except for names which are defined as macros in C) are within namespace scope (3.3.5) of the namespace std.

5. Names which are defined as macros in C shall be defined as macros in the C++ Standard Library, even if C grants license for implementation as functions. [Note: the names defined as macros in C include the following: assert, errno, offsetof, setjmp, va_arg, va_end, and va_start. —end note]
Comment 10 Jonathan Wakely 2010-06-21 16:12:15 UTC
(In reply to comment #9)
> Are these still relevant for c++0x? More so section 5 which says if they are
> macros in C they must be macros in C++

see 26.8 [c.math] paragraph 11
Comment 11 Adrian Cornish 2010-06-21 16:20:14 UTC
(In reply to comment #10)
> (In reply to comment #9)
> > Are these still relevant for c++0x? More so section 5 which says if they are
> > macros in C they must be macros in C++
> 
> see 26.8 [c.math] paragraph 11

Thanks. I should probably start using the draft rather then my dusty old 14882 copy.
Comment 12 Jonathan Wakely 2010-06-21 16:28:06 UTC
Is there a reason you changed the component back to c++?
This is not a problem in the C++ compiler front-end.
Comment 13 Adrian Cornish 2010-06-21 16:31:36 UTC
(In reply to comment #12)
> Is there a reason you changed the component back to c++?
> This is not a problem in the C++ compiler front-end.
> 
I didn't mean to change anything. All I did was reply (maybe browser cached some post back values)

My apologies - please change it to whatever it should be.
Comment 14 Jonathan Wakely 2016-01-08 00:55:06 UTC
This is yet another manifestation of Bug 14608, which I have a fix for.

*** This bug has been marked as a duplicate of bug 14608 ***