misra c 2004 pdf free download

C programming language standard, 1999 revision

This article is about the programming language dialect. For other uses, see C99 (disambiguation).

Wiki letter w.svg

This is missing information about _Pragma(), FP_CONTRACT, CX_LIMITED_RANGE. Please expand the to include this information. Further details may exist on the talk page. (November 2020)

Cover of the C99 standards document

C99 (previously known as C9X) is an informal name for ISO/IEC 9899:1999, a past version of the C programming language standard.[1] It extends the previous version (C90) with new features for the language and the standard library, and helps implementations make better use of available computer hardware, such as IEEE 754-1985 floating-point arithmetic, and compiler technology.[2] The C11 version of the C programming language standard, published in 2011, replaces C99.

History [edit]

After ANSI 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, while C++ 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 the working group ISO/IEC JTC1/SC22/WG14.

Design [edit]

1999 ISO C.pdf

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 has int 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 implicit int. In practice, compilers are likely to display a warning, then assume int and 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: variable declaration is no longer restricted to file scope or the start of a compound statement (block), facilitating static single assignment form
  • several new data types, including long long int, optional extended integer types, an explicit boolean data type, and a complex type to represent complex numbers
  • variable-length arrays (although subsequently relegated in C11 to a conditional feature that implementations are not required to support)
  • flexible array members
  • support for one-line comments beginning with //, as in BCPL, C++ and Java
  • new library functions, such as snprintf
  • new headers, such as <stdbool.h>, <complex.h>, <tgmath.h>, and <inttypes.h>
  • type-generic math (macro) functions, in <tgmath.h>, which select a math library function based upon float, double, or long double arguments, etc.
  • improved support for IEEE 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 for variadic macros (macros with a variable number of arguments)
  • restrict qualification allows more aggressive code optimization, removing compile-time array access advantages previously held by FORTRAN over ANSI C[7]
  • universal character names, which allows user variables to contain other characters than the standard character set
  • keyword static in array indices in parameter declarations[8]

Parts of the C99 standard are included in the current version of the C++ standard, including integer types, headers, and library functions. Variable-length arrays are not among these included parts because C++'s Standard Template Library already 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 of IEEE 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 754 single precision, double is defined as double precision, and long double is defined as IEEE 754 extended precision (e.g., Intel 80-bit double extended precision on x86 or x86-64 platforms), or some form of quad precision where 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 == 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), while FLT_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 of rounding errors affecting numerically unstable expressions (see IEEE 754 design rationale) and is the designed default method for x87 hardware, but yields unintuitive behavior for the unwary user;[9] FLT_EVAL_METHOD == 1 was the default evaluation method originally used in K&R C, which promoted all floats to double in expressions; and FLT_EVAL_METHOD == 0 is also commonly used and specifies a strict "evaluate to type" of the operands. (For gcc, FLT_EVAL_METHOD == 2 is the default on 32 bit x86, and FLT_EVAL_METHOD == 0 is the default on 64 bit x86-64, but FLT_EVAL_METHOD == 2 can be specified on x86-64 with option -mfpmath=387.) Before C99, compilers could round intermediate results inconsistently, especially when using x87 floating-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>                                                                double                                          compute_fn              (              double                                          z              )                                          // [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"            );                                                                                            long                                          double                                          r                                          =                                          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]                                                                                            bool                                          raised                                          =                                          fetestexcept              (              FE_OVERFLOW              );                                          // [8]                                                                        if                                    (            raised            )                                                            puts            (            "Unanticipated overflow."            );                                                                        return                                    r            ;                                    }                                                int                                    main            (            void            )                                    {                                                            #ifndef __STDC_IEC_559__                                                                    puts              (              "Warning: __STDC_IEC_559__ not defined. IEEE 754 floating point not fully supported."              );                                          // [9]                                                            

Post a Comment

0 Comments