Menu

#2244 math.h: mathematical constants undefined if GCC defines __STRICT_ANSI__

WSL
closed
None
Bug
fixed
IINR_-_Include_In_Next_Release
True
2014-12-15
2014-12-02
Thomas Uhle
No

If compiling with 'gcc -std=c++11' for instance, gcc defines __STRICT_ANSI__ and, thus, the mathematical constants in math.h from SUSv2 (see http://pubs.opengroup.org/onlinepubs/007908799/xsh/math.h.html for reference) are undefined. In addition, defining _USE_MATH_DEFINES from the MSDN documentation according to http://msdn.microsoft.com/en-us/library/4hwaceh6.aspx also does not work.
I would recommend to change the guards for the mathematical constants similar to the guards in MinGW-w64's math.h. Please see the attached patch.

1 Attachments

Discussion

  • Keith Marshall

    Keith Marshall - 2014-12-02
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -1,2 +1,2 @@
    -If compiling with 'gcc -std=c++11' for instance, gcc defines __STRICT_ANSI__ and, thus, the mathematical constants in math.h from SUSv2 (see http://pubs.opengroup.org/onlinepubs/007908799/xsh/math.h.html for reference) are undefined.  In addition, defining _USE_MATH_DEFINES from the MSDN documentation according to http://msdn.microsoft.com/en-us/library/4hwaceh6.aspx also does not work.
    +If compiling with 'gcc -std=c++11' for instance, gcc defines `__STRICT_ANSI__` and, thus, the mathematical constants in math.h from SUSv2 (see http://pubs.opengroup.org/onlinepubs/007908799/xsh/math.h.html for reference) are undefined.  In addition, defining _USE_MATH_DEFINES from the MSDN documentation according to http://msdn.microsoft.com/en-us/library/4hwaceh6.aspx also does not work.
     I would recommend to change the guards for the mathematical constants similar to the guards in MinGW-w64's math.h. Please see the attached patch.
    
    • status: unread --> open
    • Category: Known_bugs --> Unknown
     
  • Keith Marshall

    Keith Marshall - 2014-12-02

    Thanks!

    It is refreshing to see that you don't fall into the all-too-common trap of assuming that you should be able to gratuitously refer to these symbols, in the presence of a compiler switch which enables strict ANSI conformity checking. I agree with you, in principle, that there are other feature test macros which you may define, and which should relax the strictness of such conformity checking; however, I'm not convinced that your proposed patch exhibits the correct set of such macros.

    IMO, it should suffice to check:

    #if _POSIX_C_SOURCE || defined _USE_MATH_DEFINES
    /* Define non-ANSI mathematical constants as specified by POSIX.1,
    
     * (and by Microsoft, in the presence of _USE_MATH_DEFINES).
     */
     :
    

    Obviously, with the present mingwrt implementation, this alone will not suffice; to make it work correctly, _mingw.h should work harder to set up a POSIX conformity level, identified by assigning an appropriate value to _POSIX_C_SOURCE, which is consistent with any state conveyed by __STRICT_ANSI__, _GNU_SOURCE, _BSD_SOURCE, or _XOPEN_SOURCE, (or even the now-deprecated _POSIX_SOURCE).

    BTW, the reference you gave for SUSv2 is now ancient history; sure, we do need to recognize that this has been relevant since 1995, (or perhaps even earlier), but the current reference, (from POSIX.1-2008 Issue 7 (pubs.opengroup.org)) is here.

     
  • Thomas Uhle

    Thomas Uhle - 2014-12-08

    Thank you for the review!

    However, #if _POSIX_C_SOURCE won't work if _POSIX_C_SOURCE is not defined. So it should be #if defined _POSIX_C_SOURCE || defined _USE_MATH_DEFINES at least.

    You are right that _POSIX_SOURCE is deprecated in favour of _POSIX_C_SOURCE. But there are still many (maybe older) projects relying on having _POSIX_SOURCE set. So I would propose to check for both _POSIX_C_SOURCE and the former _POSIX_SOURCE as well. With _XOPEN_SOURCE and _XOPEN_SOURCE_EXTENDED it is almost the same issue. There are so many projects calling gcc by 'gcc -D_XOPEN_SOURCE=600' for instance or something alike. You generally don't want to make changes to foreign code unless it is really, really necessary.

    WRT the other feature sets, there are e.g. these two references for having

    So in the end, porting software is sometimes a tedious thing to do. I therefore prefer to alter foreign code as less as possible and, thus, would propose to check for all of these variants. (You also have something similar in _mingw.h for __USE_MINGW_ANSI_STDIO.)
    So my final proposal is then

    #if  !defined __STRICT_ANSI__  ||  defined _USE_MATH_DEFINES \
      ||  defined _POSIX_SOURCE    ||  defined _POSIX_C_SOURCE \
      ||  defined _XOPEN_SOURCE    ||  defined _XOPEN_SOURCE_EXTENDED \
      ||  defined _GNU_SOURCE      ||  defined _BSD_SOURCE
    /* Define non-ANSI mathematical constants as specified by POSIX.1,
    
     * SUSv2 (and newer), GNU C Library, BSD C Library
     * (and by Microsoft, in the presence of _USE_MATH_DEFINES).
     */
    
     
    • Keith Marshall

      Keith Marshall - 2014-12-08

      However, #if _POSIX_C_SOURCE won't work if _POSIX_C_SOURCE is not defined.

      It should; in this context, it will be evaluated as if defined, with a value of zero, and hence #if _POSIX_C_SOURCE evaluates as false. (FWIW, I too used to share your misconception; the autoconf folks set me straight).

      So it should be #if defined _POSIX_C_SOURCE || defined _USE_MATH_DEFINES at least.

      Nope. #if _POSIX_C_SOURCE || defined _USE_MATH_DEFINES is sufficient. Furthermore, none of the other feature tests you propose should be relevant here; I propose that they should be evaluated in _mingw.h, such that when explicitly defined, they implicitly define _POSIX_C_SOURCE if necessary, (with an appropriate value), so we will be able to refer to it in any other context where it may be appropriate.

       
  • Keith Marshall

    Keith Marshall - 2014-12-09

    FTR, the patch which I propose is attached.

     
  • Keith Marshall

    Keith Marshall - 2014-12-11
    • assigned_to: Keith Marshall
    • Resolution: none --> fixed
    • Category: Unknown --> IINR_-_Include_In_Next_Release
     
  • Keith Marshall

    Keith Marshall - 2014-12-11

    Fixed by commit [60ca03], with subsequent adjustment in [5fe775] to avoid unwanted side effect on __USE_MINGW_ANSI_STDIO.

     

    Related

    Commit: [5fe775]
    Commit: [60ca03]

  • Keith Marshall

    Keith Marshall - 2014-12-11
    • status: open --> closed
     
  • Thomas Uhle

    Thomas Uhle - 2014-12-15

    Thank you for patching!

     
MongoDB Logo MongoDB