Thread: Checking if the macro _POSIX_C_SOURCE is defined doesn't work

  1. #1
    Registered User
    Join Date
    Jul 2019
    Posts
    3

    Checking if the macro _POSIX_C_SOURCE is defined doesn't work

    Hello,
    I wrote a C program that relies on the sqrtf function to calculate the square root of a float, so I check if the macro _POSIX_C_SOURCE is defined before including any header. The problem is that the macro is defined (its value is 200809L) and it refuses to compile. Here's an example:
    Code:
    #ifdef _POSIX_C_SOURCE
    #include <stdio.h>
    #include <math.h>
    #endif
    
    int main(void) {
        float foo = sqrtf(3.5);
        printf("%f\n", foo);
        return 0;
    }
    And this is what I get when trying to compile it:
    Code:
    $ gcc -std=c99 -lmath -o test test.c
    test.c: In function 'main':
    test.c:7:17: warning: implicit declaration of function 'sqrtf' [-Wimplicit-function-declaration]
         float foo = sqrtf(3.5);
                     ^~~~~
    test.c:7:17: warning: incompatible implicit declaration of built-in function 'sqrtf'
    test.c:7:17: note: include '<math.h>' or provide a declaration of 'sqrtf'
    test.c:8:5: warning: implicit declaration of function 'printf' [-Wimplicit-function-declaration]
         printf("%g\n", foo);
         ^~~~~~
    test.c:8:5: warning: incompatible implicit declaration of built-in function 'printf'
    test.c:8:5: note: include '<stdio.h>' or provide a declaration of 'printf'
    /usr/bin/ld: cannot find -lmath
    collect2: error: ld returned 1 exit status
    Why aren't the headers included?
    Thanks in advance.

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    I think that GCC leaves non-standard macros undefined when you ask for "c99". Try "gnu99" instead.
    Devoted my life to programming...

  3. #3
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    sqrtf is in C99. You don't need POSIX for that function.

    Besides, _POSIX_C_SOURCE is a user-defined macro; it's up to you to define that macro to tell the implementation to conform to a particular version of POSIX.

    Lastly, gcc takes -lm (not -lmath) to link in the math library.

  4. #4
    Registered User
    Join Date
    Jul 2019
    Posts
    3
    Quote Originally Posted by GReaper View Post
    I think that GCC leaves non-standard macros undefined when you ask for "c99". Try "gnu99" instead.
    It doesn't work either:
    Code:
    $ gcc -std=gnu99 -lmath -o test test.c 
    test.c: In function 'main':
    test.c:7:17: warning: implicit declaration of function 'sqrtf' [-Wimplicit-function-declaration]
         float foo = sqrtf(3.5);
                     ^~~~~
    test.c:7:17: warning: incompatible implicit declaration of built-in function 'sqrtf'
    test.c:7:17: note: include '<math.h>' or provide a declaration of 'sqrtf'
    test.c:8:5: warning: implicit declaration of function 'printf' [-Wimplicit-function-declaration]
         printf("%f\n", foo);
         ^~~~~~
    test.c:8:5: warning: incompatible implicit declaration of built-in function 'printf'
    test.c:8:5: note: include '<stdio.h>' or provide a declaration of 'printf'
    /usr/bin/ld: cannot find -lmath
    collect2: error: ld returned 1 exit status
    And the macro is standard:
    A POSIX-conforming application shall ensure that the feature test macro _POSIX_C_SOURCE is defined before inclusion of any header.
    Source: The Open Group Base Specifications Issue 7, 2018 edition

    Quote Originally Posted by christop View Post
    sqrtf is in C99. You don't need POSIX for that function.

    Besides, _POSIX_C_SOURCE is a user-defined macro; it's up to you to define that macro to tell the implementation to conform to a particular version of POSIX.

    Lastly, gcc takes -lm (not -lmath) to link in the math library.
    I see. But I thought the objective of the macro is to check if it's defined, and if it is, I can safely use the extends to the ISO C standard. And the macro does have a value defined, because when I write it using Code::Blocks, it says its value is 200809L.
    Last edited by Inarrebla; 07-16-2019 at 02:16 PM.

  5. #5
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    It appears that gcc is being somewhat "helpful" by defining _POSIX_C_SOURCE when you include one of the standard headers if _GNU_SOURCE is defined (see /usr/include/sys/features.h). _GNU_SOURCE is defined when you use -std=gnu99 but not -std=c99.

    Still, from POSIX's standpoint, the application (the program you're writing) is responsible for defining _POSIX_C_SOURCE. From what I can see, gcc simply relaxes that requirement by defining it for you when you compile with one of the "gnuXX" standards.

    If you want full control over it, use "-std=c99" and define the macro yourself, either in the source code or with the option "-D_POSIX_C_SOURCE=200809L" when you compile.

  6. #6
    Registered User
    Join Date
    Jul 2019
    Posts
    3
    You're absolutely right christop, the sqrtf function is available in C99 according to cppreference.com: sqrt, sqrtf, sqrtl - cppreference.com. I should have looked there before making any assumptions when reading the POSIX math.h header documentation.

    And it seems I completely misunderstood the documentation. This is what misled me to believe the macro is already defined on POSIX systems:
    In the compilation of an application that #defines a feature test macro specified by POSIX.1-2017, no header defined by POSIX.1-2017 shall be included prior to the definition of the feature test macro. This restriction also applies to any implementation-provided header in which these feature test macros are used. If the definition of the macro does not precede the #include, the result is undefined.
    But when I read it again I notice it clearly states it's me the one who has to define the macro. I'm sorry I asked this just because of this.
    And thank you all for your help.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Checking a macro's sign in order to define other macro
    By Egalestrenge in forum C Programming
    Replies: 5
    Last Post: 05-23-2016, 09:39 PM
  2. Testing if a macro is defined to a value?
    By homer_3 in forum C Programming
    Replies: 4
    Last Post: 01-17-2015, 04:35 AM
  3. Overloading operator new when a macro new is defined
    By rjzak in forum C++ Programming
    Replies: 4
    Last Post: 03-30-2011, 03:57 PM
  4. Replies: 1
    Last Post: 12-07-2010, 06:53 AM
  5. Checking that a file doesn't exist already
    By Gades in forum C Programming
    Replies: 2
    Last Post: 10-26-2001, 03:00 AM

Tags for this Thread