Standards.md

September 8, 2025 ยท View on GitHub

Please send updates/corrections to predef-contribute or through pull requests on GitHub.

Language Standards

Language standards requires the existence of pre-defined macros.

NameMacroStandard
C89__STDC__ANSI X3.159-1989
C90__STDC__ISO/IEC 9899:1990
C94__STDC_VERSION__ = 199409LISO/IEC 9899-1:1994
C99__STDC_VERSION__ = 199901LISO/IEC 9899:1999
C11__STDC_VERSION__ = 201112LISO/IEC 9899:2011
C17__STDC_VERSION__ = 201710LISO/IEC 9899:2018
C23__STDC_VERSION__ = 202311LISO/IEC 9899:2024
C++98__cplusplus = 199711LISO/IEC 14882:1998
C++11__cplusplus = 201103LISO/IEC 14882:2011
C++14__cplusplus = 201402LISO/IEC 14882:2014
C++17__cplusplus = 201703LISO/IEC 14882:2017
C++20__cplusplus = 202002LISO/IEC 14882:2020
C++23__cplusplus = 202302LISO/IEC 14882:2024
C++/CLI__cplusplus_cli = 200406LECMA-372
DSP-CISO/IEC JTC1/SC22 WG14/N854
EC++__embedded_cplusplusEmbedded C++
Example: C Standards
#if defined(__STDC__)
# define PREDEF_STANDARD_C_1989
# if defined(__STDC_VERSION__)
# if (__STDC_VERSION__ >= 199409L)
# define PREDEF_STANDARD_C_1994
# endif
# if (__STDC_VERSION__ >= 199901L)
# define PREDEF_STANDARD_C_1999
# endif
# endif
#endif

Notice that not all compliant compilers provides the correct pre-defined macros. For example, Microsoft Visual C++ does not define __STDC__, or Sun Workshop 4.2 supports C94 without setting __STDC_VERSION__ to the proper value. Extra checks for such compilers must be added.

Notice that some compilers, such as the HP aC++, use the value 199707L to indicate the C++98 standard. This value was used in an earlier proposal of the C++98 standard.

Example: Pre-C89

In continuation of the above example, pre-C89 compilers do not recognize certain keywords. Let the preprocessor remove those keywords for those compilers.

#if !defined(PREDEF_STANDARD_C_1989) && !defined(__cplusplus)
# define const
# define volatile
#endif

Unix Standards

There are several related Unix standards, such as POSIX, X/Open, and LSB.

Unix standards require the existence macros in the <unistd.h> header file.

NameMacroStandard
POSIX.1-1988_POSIX_VERSION = 198808L
POSIX.1-1990_POSIX_VERSION = 199009LISO/IEC 9945-1:1990
POSIX.2_POSIX2_C_VERSION = 199209LISO/IEC 9945-2:1993
POSIX.1b-1993_POSIX_VERSION = 199309LIEEE 1003.1b-1993
POSIX.1-1996_POSIX_VERSION = 199506LIEEE 1003.1-1996
POSIX.1-2001_POSIX_VERSION = 200112LIEEE 1003.1-2001
POSIX.1-2008_POSIX_VERSION = 200809LIEEE 1003.1-2008
XPG3_XOPEN_VERSION = 3X/Open Portability Guide 3 (1989)
XPG4_XOPEN_VERSION = 4X/Open Portability Guide 4 (1992)
SUS_XOPEN_VERSION = 4 && _XOPEN_UNIXX/Open Single UNIX Specification (UNIX95)
SUSv2_XOPEN_VERSION = 500X/Open Single UNIX Specification, Version 2 (UNIX98)
SUSv3_XOPEN_VERSION = 600Open Group Single UNIX Specification, Version 3 (UNIX03)
SUSv4_XOPEN_VERSION = 700Open Group Single UNIX Specification, Version 4
LSB__LSB_VERSION__ = VRLinux Standards Base

V = Version
R = Revision
Example: Unix Standards

The following examples assumes the definition of these macros.

#if defined(unix) || defined(__unix__) || defined(__unix)
# define PREDEF_PLATFORM_UNIX
#endif
#if defined(PREDEF_PLATFORM_UNIX)
# include <unistd.h>
# if defined(_XOPEN_VERSION)
# if (_XOPEN_VERSION >= 3)
# define PREDEF_STANDARD_XOPEN_1989
# endif
# if (_XOPEN_VERSION >= 4)
# define PREDEF_STANDARD_XOPEN_1992
# endif
# if (_XOPEN_VERSION >= 4) && defined(_XOPEN_UNIX)
# define PREDEF_STANDARD_XOPEN_1995
# endif
# if (_XOPEN_VERSION >= 500)
# define PREDEF_STANDARD_XOPEN_1998
# endif
# if (_XOPEN_VERSION >= 600)
# define PREDEF_STANDARD_XOPEN_2003
# endif
# if (_XOPEN_VERSION >= 700)
# define PREDEF_STANDARD_XOPEN_2008
# endif
# endif
#endif

Notice that not all compliant compilers provides the correct pre-defined macros. For example, IBM xlC supports Unix without setting any of the __unix__ macros. Extra checks for such compilers must be added.