Search code examples
cclangc-standard-libraryxcode-command-line-tools

Can I disable or ignore Apple additions to C standard headers?


I'm developing a C application that I would like to be reasonably portable. It builds ok with with gcc and clang on Linux, and with MSVC on Windows. After getting access to a Mac I tried building with the Command Line Tools.

It fails to compile because my code declares a function isnumber and Apple's ctype.h header also declares a (non standard?) isnumber. I can rename my function so it doesn't conflict, but is there a way to avoid this by disabling or ignoring all, or specific, Apple additions to standard headers? E.g. is there a compiler option or preprocessor pragma to ignore them?

My isnumber is unrealated to checking character classes. Below is code that reproduces the issue - it compiles with clang/Linux and MSVC/Windows but not on a Mac ( - it is not the actual code).

#include <ctype.h>
#include <stdio.h>

char *isnumber(void);

int main(void)
{
    char *opt = "A";

    if (isupper(*opt))
        printf("THE IS NUMBER IS: %s\n", isnumber());
    else
        printf("The IS number is: %s\n", isnumber());

    return 0;
}

char *isnumber(void)
{
    return "IS-123";
}

Error:

/Users/ ... /repro/main.c:4:7: error: conflicting types for 'isnumber'
char *isnumber(void);
      ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/_ctype.h:323:1: note: previous definition is here
isnumber(int _c)

Update:

As Acorn's answer and it's comments describe, 'isnumber' is a BAD name for a function as the C11 standard reserves it:

7.31 Future library directions
The following names are grouped under individual headers for convenience. All external names described below are reserved no matter what headers are included by the program.

...

7.31.2 Character handling <ctype.h>
"Function names that begin with either is or to, and a lowercase letter may be added to the declarations in the <ctype.h> header".

So the 'correct' solution to my original problem is for me to rename my functions.


Solution

  • Yes, they can be disabled. But before disabling anything I strongly suggest reading Acorn's answer. Just because you can disable them, it doesn't mean you should. For example, attempting to disable the Apple additions was the wrong solution in my case. But my question was 'Can ...' not 'Should ...'.

    They can be disabled by adding #define _POSIX_C_SOURCE or #define _ANSI_SOURCE before #include ctype.h. This will 'disable' the Apple additons to the library, e.g.:

    #define _POSIX_C_SOURCE
    
    #include <ctype.h>
    #include <stdio.h>
    ...
    

    If you only want to define this when on maxOS you can first check for the system defined macro __MACH__, (see this question), e.g.:

    #ifdef __MACH__
    #define _POSIX_C_SOURCE
    #endif
    
    #include <ctype.h>
    #include <stdio.h>
    ...
    
    Explanation:

    Apple's ctype.h includes _ctype.h where the additional declarations and definitions are guarded by:

    #if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))
    

    Thank you to FelixG who first to pointed me in this direction.