Jump to content

C99

From Wikipedia, the free encyclopedia

Cover of the C99 standards document

C99(previouslyC9X,formallyISO/IEC 9899:1999) is a past version of theCprogramming 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]TheC11version of the C programming language standard, published in 2011, updates C99.

History

[edit]

AfterANSIproduced 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.

Design

[edit]

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 hasintimplicitly 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 assumeintand continue translating the program.

C99 introduced several new features, many of which had already been implemented as extensions in several compilers:[4]

  • inline functions
  • intermingled declarations and code:variabledeclaration is no longer restricted to file scope or the start of a compound statement (block)
  • several newdata types,includinglong long int,optional extended integer types, an explicitBoolean data type,and acomplextype to representcomplex numbers
  • variable-length arrays(although subsequently relegated inC11to a conditional feature that implementations are not required to support)
  • flexible array members
  • support for one-linecommentsbeginning with//,as inBCPL,C++andJava
  • new library functions, such assnprintf
  • newheaders,such as<stdbool.h>,<complex.h>,<tgmath.h>,and<inttypes.h>
  • type-generic math (macro) functions, in<tgmath.h>,which select amath libraryfunctionbased uponfloat,double,orlong doublearguments, etc.
  • improved support forIEEE floating point
  • designated initializers (for example, initializing a structure by field names:struct point p = {.x = 1,.y = 2 };)[5]
  • compound literals (for instance, it is possible to construct structures in function calls:function((struct x) {1, 2}))[6]
  • support forvariadic macros(macros with a variable number of arguments)
  • restrictqualification allows more aggressive codeoptimization,removing compile-time array access advantages previously held byFORTRANover ANSI C[7]
  • universal character names, which allows user variables to contain other characters than the standard character set: four-digit\u0040or eight-digit hexadecimal sequences\U0001f431
  • keywordstaticin 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 Libraryalready includes similar functionality.

IEEE 754 floating-point support

[edit]

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-pointhardware 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:

  • floatis defined as IEEE 754single precision,doubleis defined asdouble precision,andlong doubleis defined as IEEE 754extended precision(e.g., Intel 80-bitdouble extendedprecision onx86orx86-64platforms), or some form ofquad precisionwhere available; otherwise, it is double precision.
  • The four arithmetic operations and square root are correctly rounded as defined by IEEE 754.
    FLT_EVAL_METHOD float double long double
    0 float double long double
    1 double double long double
    2 long double long double long double
  • Expression evaluation is defined to be performed in one of three well-defined methods, indicating whether floating-point variables are first promoted to a more precise format in expressions:FLT_EVAL_METHOD == 2indicates 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 == 1performs all internal intermediate expressions in double precision (unless an operand is long double), whileFLT_EVAL_METHOD == 0specifies 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 == 2tends to limit the risk ofrounding errorsaffecting numerically unstable expressions (seeIEEE 754 design rationale) and is the designed default method forx87hardware, but yields unintuitive behavior for the unwary user;[9]FLT_EVAL_METHOD == 1was the default evaluation method originally used inK&R C,which promoted all floats to double in expressions; andFLT_EVAL_METHOD == 0is also commonly used and specifies a strict "evaluate to type" of the operands. (Forgcc,FLT_EVAL_METHOD == 2is the default on 32 bit x86, andFLT_EVAL_METHOD == 0is the default on 64 bit x86-64, butFLT_EVAL_METHOD == 2can be specified on x86-64 with option -mfpmath=387.) Before C99, compilers could round intermediate results inconsistently, especially when usingx87floating-point hardware, leading to compiler-specific behaviour;[10]such inconsistencies are not permitted in compilers conforming to C99 (annex F).

Example

[edit]

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_UP
fesetround(FE_UPWARD);// [10]
#elif TEST_NUMERIC_STABILITY_DOWN
fesetround(FE_DOWNWARD);
#endif

printf("%.7g\n",compute_fn(3.0));
printf("%.7g\n",compute_fn(NAN));

return0;
}

Footnotes:

  1. Compile with:gcc-std=c99-mfpmath=387-otest_c99_fptest_c99_fp.c-lm
  2. As the IEEE 754 status flags are manipulated in this function, this #pragma is needed to avoid the compiler incorrectly rearranging such tests when optimising. (Pragmas are usually implementation-defined, but those prefixed withSTDCare defined in the C standard.)
  3. C99 defines a limited number of expression evaluation methods: the current compilation mode can be checked to ensure it meets the assumptions the code was written under.
  4. The special values such asNaNand positive or negative infinity can be tested and set.
  5. long doubleis 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_tcan be used for code that is portable under allFLT_EVAL_METHODs).
  6. The main function to be evaluated. Although it appears that some arguments to this continued fraction, e.g., 3.0, would lead to a divide-by-zero error, in fact the function is well-defined at 3.0 and division by 0 will simply return a +infinity that will then correctly lead to a finite result: IEEE 754 is defined not to trap on such exceptions by default and is designed so that they can very often be ignored, as in this case. (IfFLT_EVAL_METHODis defined as 2 then all internal computations including constants will be performed in long double precision; ifFLT_EVAL_METHODis defined as 0 then additional care is need to ensure this, including possibly additional casts and explicit specification of constants as long double.)
  7. As the raised divide-by-zero flag is not an error in this case, it can simply be dismissed to clear the flag for use by later code.
  8. In some cases, other exceptions may be regarded as an error, such as overflow (although it can in fact be shown that this cannot occur in this case).
  9. __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).
  10. The default rounding mode is round to nearest (with the even rounding rule in the halfway cases) for IEEE 754, but explicitly setting the rounding mode toward + and - infinity (by definingTEST_NUMERIC_STABILITY_UPetc. 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.

Version detection

[edit]

A standard macro__STDC_VERSION__is defined with value199901Lto 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 thatinlineis available in either case (by replacing it withstaticin C90 to avoid linker errors).

#if __STDC_VERSION__ >= 199901L
/* "inline" is a keyword */
#else
# define inline static
#endif

Implementations

[edit]

Most C compilers provide support for at least some of the features introduced in C99.

Historically,Microsofthas 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]

Future work

[edit]

Since ratification of the 1999 C standard, the standards working group prepared technical reports specifying improved support for embedded processing, additional character data types (Unicodesupport), and library functions with improvedbounds checking.Work continues on technical reports addressing decimalfloating point,additional mathematicalspecial functions,and additionaldynamic memory allocationfunctions. The C and C++ standards committees have been collaborating on specifications forthreadedprogramming.

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 pointsand to supportthreadedprogramming.

See also

[edit]

References

[edit]
  1. ^"ISO/IEC 9899:1999 - Programming languages - C".Iso.org. 8 December 2011.Retrieved8 April2014.
  2. ^ab"IEEE 754 Support in C99"(PDF).IEEE.Archived fromthe original(PDF)on 28 October 2017.Retrieved15 July2021.
  3. ^"Standards - Using the GNU Compiler Collection (GCC)".Gcc.gnu.org.Retrieved8 April2014.
  4. ^"C Dialect Options - Using the GNU Compiler Collection (GCC)".Gcc.gnu.org. 6 May 2009.Retrieved8 April2014.
  5. ^"Using the GNU Compiler Collection (GCC): Designated Initializers".gnu.org.Retrieved18 September2019.
  6. ^"Using the GNU Compiler Collection (GCC): Compound Literals".gnu.org.Retrieved31 January2016.
  7. ^Ulrich Drepper (23 October 2007)."What every programmer should know about memory".LWN.net.Retrieved3 April2015.
  8. ^ISO/IEC 9899:1999 specification, TC3(PDF).p. 119, § 6.7.5.3Function declarators (including prototypes)para. 7.
  9. ^Doug Priest (1997)."Differences Among IEEE 754 Implementations".
  10. ^Jack Woehr (1 November 1997)."A conversation with William Kahan".
  11. ^William Kahan (11 June 1996)."The Baleful Effect of Computer Benchmarks upon Applied Mathematics, Physics and Chemistry"(PDF).
  12. ^William Kahan (11 January 2006)."How Futile are Mindless Assessments of Roundoff in Floating-Point Computation?"(PDF).
  13. ^Peter Bright (29 June 2013)."C99 acknowledged at last as Microsoft lays out its path to C++14".Ars Technica.Retrieved9 January2015.
  14. ^abcBrenner, Pat."What's New for Visual C++ in Visual Studio 2015".Microsoft Developer Network.Retrieved27 April2015.
  15. ^"Using the x86 Open64 Compiler Suite"(PDF).Developer.amd.Archived(PDF)from the original on 24 January 2022.Retrieved2 March2022.
  16. ^"cc65 - a freeware C compiler for 6502 based systems".Retrieved14 September2011.
  17. ^"C/C++ interpreter Ch C99 features".SoftIntegration, Inc. 15 February 2008.Retrieved15 February2008.
  18. ^"Clang Compiler User's Manual".Retrieved14 October2017.
  19. ^"The CompCert C verified compiler documentation and user's manual (Version 3.10)".19 November 2021.Retrieved3 March2022.
  20. ^"libfirm homepage".Retrieved4 February2014.
  21. ^"C Language Implementation - Digital Mars".Retrieved14 September2011.
  22. ^"Status of C99 features in GCC".Free Software Foundation, Inc. 28 July 2021.Retrieved13 August2021.
  23. ^"Status of C99 features in GCC 4.6".Free Software Foundation, Inc. 23 May 2013.Retrieved23 May2013.
  24. ^"Status of C99 features in GCC 4.7".Free Software Foundation, Inc. 23 May 2013.Retrieved23 May2013.
  25. ^"Semantics of Floating Point Math in GCC".20 July 2018.Retrieved12 August2018.
  26. ^"IBM C for AIX, V6.0 Now Supports the C99 Standard".2 July 2002.Retrieved31 January2016.
  27. ^"IBM - XL C/C++ for AIX".Retrieved31 January2016.
  28. ^"IBM Rational Logiscope support for C99 standard - United States".24 February 2012.Retrieved31 January2016.
  29. ^"Reader Q&A: What about VC++ and C99?".Sutter’s Mill.3 May 2012.Retrieved31 January2016.
  30. ^"A.27 Use of C99 Variable Length Arrays".Microsoft.Retrieved31 January2016.
  31. ^"Microsoft to C99 Developers: Use ISO C++".InfoQ.Retrieved31 January2016.
  32. ^"C99 library support in Visual Studio 2013".Microsoft. 19 July 2013.Retrieved31 January2016.
  33. ^"C++11/14 STL Features, Fixes, And Breaking Changes In VS 2013".Blogs.msdn. 28 June 2013.Retrieved8 April2014.
  34. ^"Announcing full support for a C/C++ conformant preprocessor in MSVC".Microsoft. 27 March 2020.Retrieved17 September2020.
  35. ^"C99 compliance in Open Watcom".Archived fromthe originalon 3 May 2015.Retrieved25 September2015.
  36. ^"Pelles C Overview".January 2013. Archived fromthe originalon 13 March 2022.Retrieved2 March2022.
  37. ^"Sun Studio 12: C Compiler 5.9 Readme".Sun Microsystems, Inc. 31 May 2007.Retrieved23 September2012.
  38. ^"Tiny C Compiler Reference Documentation".Retrieved31 January2016.
  39. ^According to the project'sTODO listcomplex types are the only missing C99 feature. Variable Length Arrays have been added in TCC 0.9.26[1]
  40. ^"TCC: Tiny C Compiler".Retrieved31 January2016.
  41. ^"Standards - Using the GNU Compiler Collection (GCC)".Gcc.gnu.org.Retrieved8 April2014.

Further reading

[edit]
[edit]
Preceded by C languagestandards Succeeded by