Thisis missing information about _Pragma(), FP_CONTRACT, CX_LIMITED_RANGE. Please expand the to include this information. Further details may exist on thetalk page.(November 2020) |
C language revisions |
---|
C99 (previouslyC9X, formallyISO/IEC 9899:1999) is a past version of theC programming languageopen standard.[1] It extends the previous version (C90) with new features for the language and thestandard library, and helps implementations make better use of available computer hardware, such asIEEE 754-1985floating-point arithmetic, and compiler technology.[2] TheC11 version of the C programming language standard, published in 2011, updates C99.
AfterANSI produced the official standard for the C programming language in 1989, which became an international standard in 1990, the C language specification remained relatively static for some time, whileC++ continued to evolve, largely during its own standardization effort. Normative Amendment 1 created a new standard for C in 1995, but only to correct some details of the 1989 standard and to add more extensive support for international character sets. The standard underwent further revision in the late 1990s, leading to the publication of ISO/IEC 9899:1999 in 1999, which was adopted as an ANSI standard in May 2000. The language defined by that version of the standard is commonly referred to as "C99". The international C standard is maintained by theworking groupISO/IEC JTC1/SC22/WG14.
C99 is, for the most part, backward compatible with C89, but it is stricter in some ways.[3]
In particular, a declaration that lacks a type specifier no longer hasint
implicitly assumed. The C standards committee decided that it was of more value for compilers to diagnose inadvertent omission of the type specifier than to silently process legacy code that relied on implicitint
. In practice, compilers are likely to display a warning, then assumeint
and continue translating the program.
C99 introduced several new features, many of which had already been implemented as extensions in several compilers:[4]
long long int
, optional extended integer types, an explicitBoolean data type, and acomplex
type to representcomplex numbers//
, as inBCPL,C++ andJavasnprintf
<stdbool.h>
,<complex.h>
,<tgmath.h>
, and<inttypes.h>
<tgmath.h>
, which select amath libraryfunction based uponfloat
,double
, orlong double
arguments, etc.struct point p = { .x = 1, .y = 2 };
[5]function((struct x) {1, 2})
[6]restrict
qualification allows more aggressive codeoptimization, removing compile-time array access advantages previously held byFORTRAN over ANSI C[7]\u0040
or eight-digit hexadecimal sequences\U0001f431
static
in array indices in parameter declarations[8]Parts of the C99 standard are included in the current version of theC++ standard, including integer types, headers, and library functions. Variable-length arrays are not among these included parts because C++'sStandard Template Library already includes similar functionality.
A major feature of C99 is its numerics support, and in particular its support for access to the features ofIEEE 754-1985 (also known as IEC 60559)floating-point hardware present in the vast majority of modern processors (defined in "Annex F IEC 60559 floating-point arithmetic"). Platforms without IEEE 754 hardware can also implement it in software.[2]
On platforms with IEEE 754 floating point:
float
is defined as IEEE 754single precision,double
is defined asdouble precision, andlong double
is defined as IEEE 754extended precision (e.g., Intel 80-bitdouble extended precision onx86 orx86-64 platforms), or some form ofquad precision where available; otherwise, it is double precision.FLT_EVAL_METHOD | float | double | long double |
---|---|---|---|
0 | float | double | long double |
1 | double | double | long double |
2 | long double | long double | long double |
FLT_EVAL_METHOD == 2
indicates that all internal intermediate computations are performed by default at high precision (long double) where available (e.g.,80 bit double extended),FLT_EVAL_METHOD == 1
performs all internal intermediate expressions in double precision (unless an operand is long double), whileFLT_EVAL_METHOD == 0
specifies each operation is evaluated only at the precision of the widest operand of each operator. The intermediate result type for operands of a given precision are summarized in the adjacent table.FLT_EVAL_METHOD == 2
tends to limit the risk ofrounding errors affecting numerically unstable expressions (seeIEEE 754 design rationale) and is the designed default method forx87 hardware, but yields unintuitive behavior for the unwary user;[9]FLT_EVAL_METHOD == 1
was the default evaluation method originally used inK&R C, which promoted all floats to double in expressions; andFLT_EVAL_METHOD == 0
is also commonly used and specifies a strict "evaluate to type" of the operands. (Forgcc,FLT_EVAL_METHOD == 2
is the default on 32 bit x86, andFLT_EVAL_METHOD == 0
is the default on 64 bit x86-64, butFLT_EVAL_METHOD == 2
can be specified on x86-64 with option -mfpmath=387.) Before C99, compilers could round intermediate results inconsistently, especially when usingx87 floating-point hardware, leading to compiler-specific behaviour;[10] such inconsistencies are not permitted in compilers conforming to C99 (annex F).
The following annotated example C99 code for computing a continued fraction function demonstrates the main features:
#include<stdio.h>#include<math.h>#include<float.h>#include<fenv.h>#include<tgmath.h>#include<stdbool.h>#include<assert.h>doublecompute_fn(doublez)// [1]{#pragma STDC FENV_ACCESS ON// [2]assert(FLT_EVAL_METHOD==2);// [3]if(isnan(z))// [4]puts("z is not a number");if(isinf(z))puts("z is infinite");longdoubler=7.0-3.0/(z-2.0-1.0/(z-7.0+10.0/(z-2.0-2.0/(z-3.0))));// [5, 6]feclearexcept(FE_DIVBYZERO);// [7]boolraised=fetestexcept(FE_OVERFLOW);// [8]if(raised)puts("Unanticipated overflow.");returnr;}intmain(void){#ifndef __STDC_IEC_559__puts("Warning: __STDC_IEC_559__ not defined. IEEE 754 floating point not fully supported.");// [9]#endif#pragma STDC FENV_ACCESS ON#ifdef TEST_NUMERIC_STABILITY_UPfesetround(FE_UPWARD);// [10]#elif TEST_NUMERIC_STABILITY_DOWNfesetround(FE_DOWNWARD);#endifprintf("%.7g\n",compute_fn(3.0));printf("%.7g\n",compute_fn(NAN));return0;}
Footnotes:
gcc-std=c99-mfpmath=387-otest_c99_fptest_c99_fp.c-lm
STDC
are defined in the C standard.)long double
is defined as IEEE 754 double extended or quad precision if available. Using higher precision than required for intermediate computations can minimizeround-off error[11] (thetypedefdouble_t
can be used for code that is portable under allFLT_EVAL_METHOD
s).FLT_EVAL_METHOD
is defined as 2 then all internal computations including constants will be performed in long double precision; ifFLT_EVAL_METHOD
is defined as 0 then additional care is need to ensure this, including possibly additional casts and explicit specification of constants as long double.)__STDC_IEC_559__
is to be defined only if "Annex F IEC 60559 floating-point arithmetic" is fully implemented by the compiler and the C library (users should be aware that this macro is sometimes defined while it should not be).TEST_NUMERIC_STABILITY_UP
etc. in this example, when debugging) can be used to diagnose numerical instability.[12] This method can be used even ifcompute_fn()
is part of a separately compiled binary library. But depending on the function, numerical instabilities cannot always be detected.A standard macro__STDC_VERSION__
is defined with value199901L
to indicate that C99 support is available. As with the__STDC__
macro for C90,__STDC_VERSION__
can be used to write code that will compile differently for C90 and C99 compilers, as in this example that ensures thatinline
is available in either case (by replacing it withstatic
in C90 to avoid linker errors).
#if __STDC_VERSION__ >= 199901L/* "inline" is a keyword */#else# define inline static#endif
Most C compilers provide support for at least some of the features introduced in C99.
Historically,Microsoft has been slow to implement new C features in theirVisual C++ tools, instead focusing mainly on supporting developments in the C++ standards.[13] However, with the introduction of Visual C++ 2013 Microsoft implemented a limited subset of C99, which was expanded in Visual C++ 2015.[14]
Compiler | Level of support | C99 compatibility details |
---|---|---|
Acorn C/C++ | Partial | The official documentation states that "most" compiler features are supported, along with "some" of the library functions. |
AMD x86 Open64 Compiler Suite | Mostly | Has C99 support equal to that of GCC.[15] |
cc65 | Partial | FullC89 and C99 support is not implemented, partly due to platform limitations (MOS Technology 6502). There is no support planned for some C99 types like _Complex and 64-bit integers (long long).[16] |
Ch | Partial | Supports major C99 features.[17] |
Clang | Mostly | Supports all features except C99 floating-point pragmas.[18] |
CompCert | Mostly | A certified compiler, formally proved correct. Supports all features except C99 complex numbers and VLA, and minor restrictions on switch statements (noDuff's device).[19] |
cparser | Full | Supports C99 features.[20] |
C++ Builder | Only in 64-bit mode, since latter is CLang fork [citation needed] | |
Digital Mars C/C++ Compiler | Partial | Lacks support for some features, such as <tgmath.h> and _Pragma.[21] |
GCC | Mostly | As of July 2021[update], standard pragmas and IEEE 754/IEC 60559 floating-point support are missing in mainline GCC. Additionally, some features (such as extended integer types and new library functions) must be provided by the C standard library and are out of scope for GCC.[22] GCC's 4.6 and 4.7 releases also provide the same level of compliance.[23][24] Partial IEEE 754 support, even when the hardware is compliant: some compiler options may be needed to avoid incorrect optimizations (e.g.,-std=c99 and-fsignaling-nans ), but full support of directed rounding modes is missing even when-frounding-math is used.[25] |
Green Hills Software | Full | |
IBM C for AIX, V6[26] andXL C/C++ V11.1 for AIX[27] | Full | |
IBM Rational logiscope | Full | Until Logiscope 6.3, only basic constructs of C99 were supported. C99 is officially supported in Logiscope 6.4 and later versions.[28] |
The Portland Group PGI C/C++ | Full | |
IAR Systems Embedded Workbench | Mostly | Does not support UCN (universal character names). Compiler for embedded targets, such as ARM, Coldfire, MSP430, AVR, AVR32, 8051, ... No x86 targets. |
Intel C++ compiler | Mostly [citation needed] | |
Microsoft Visual C++ | Partial[14] | Visual C++ 2012 and earlier did not support C99.[29][30][31] Visual C++ 2013 implements a limited subset of C99 required to compile popular open-source projects.[32][33] Visual C++ 2015 implements the C99 standard library, with the exception of any library features that depend on compiler features not yet supported by the compiler (for example, <tgmath.h> is not implemented).[14] Visual C++ 2019 (16.6) adds opt-in support for a C99 conformant preprocessor.[34] |
Open Watcom | Partial | Implements the most commonly used parts of the standard. However, they are enabled only through the undocumented command-line switch "-za99". Three C99 features have been bundled as C90 extensions since pre-v1.0: C++ style comments (//), flexible array members, trailing comma allowed in enum declaration.[35] |
Pelles C | Full | Supports all C99 features.[36] |
Portable C compiler | Partial | Working towards becoming C99-compliant.[citation needed] |
Sun Studio | Full[37] | |
TheAmsterdam Compiler Kit | No[citation needed] | A C99 frontend is currently under investigation.[citation needed] |
Tiny C Compiler | Partial | Does not support complex numbers.[38][39] Variable Length Arrays are supported but not as arguments in functions[citation needed]. The developers state that "TCC is heading toward full ISOC99 compliance".[40] |
vbcc | Partial |
Since ratification of the 1999 C standard, the standards working group prepared technical reports specifying improved support for embedded processing, additional character data types (Unicode support), and library functions with improvedbounds checking. Work continues on technical reports addressing decimalfloating point, additional mathematicalspecial functions, and additionaldynamic memory allocation functions. The C and C++ standards committees have been collaborating on specifications forthreaded programming.
The next revision of the C standard,C11, was ratified in 2011.[41] The C standards committee adopted guidelines that limited the adoption of new features that have not been tested by existing implementations. Much effort went into developing amemory model, in order to clarifysequence points and to supportthreaded programming.
Preceded by | C language standards | Succeeded by |