C89

Table of contents 1 Definition of terms
2 Types
3 Scopes and linkages
4 Constants
5 Initialization
6 Structures, unions, and enumerations
7 Pointers and arrays
8 Functions
9 Operators
10 Statements
11 Preprocessing directives

Definition of terms

A comment is introduced, except within character constant, string literal, or comment, by characters /* and contents of comment are examined only to identify characters */ which terminate it.

A compound statement (block) groups a set of statements into a syntactic unit between { and }, which may have its own declarations, and initializations.

A declaration is a sequence of declaration specifiers, followed by a comma separated sequence of declarators. A definition is a declarationwhich also reserves storage. Declaration specifier indicates linkage, storage duration, and type. Declarator declares an identifier, so thatin expression this identifier designates function or object, with linkage, storage duration, and type indicated by declaration specifiers. Declarator may include type information, or an initializer.

An expression is a sequence of operators and operands, for generating effects, such as computing a value or designator. An operator specifiesoperation on operand(s).

An identifier is a sequence of nondigit characters (including underscore -) and digits (first character is nondigit), which is not identical to a keyword, and denotes an object, function, tag, typedef name, label name, macro name, macro parameter, or a member of structure, union, or enumeration. At least the first 31 characters are significant; lower-case and upper-case letters are different. For an identifier with external linkage, at least six characters are significant, and alphabetical case may be ignored.

A keyword is one of auto, double, int, struct, break, else, long, switch, case, enum, register, typedef, char, extern, return, union, const, float, short, unsigned, continue, for, signed, void, default, goto, sizeof, volatile, do, if, static, while.

An lvalue is an expression which designates object. A modifiable lvalue shall not have array type, incomplete type, const-qualified type, or structure or union member with const-qualified type.

A name space disambiguates label names, tags of structures, unions, enumerations, and other identifiers, if several declarations of anidentifier are visible. A structure or union has a separate name space for its members.

An object is a region of data storage, which is aligned on boundaries, which are multiples of a byte address.

A parameter is an object with automatic storage duration, which is declared in function declaration or macro definition. A parameter acquires a value on entry to function.

A punctuator (one of [ ] ( ) { } * , : = ; … #) is a symbol, which has a syntactic and semantic significance, but does not specify an operation, which yields a value.

A storage-class specifiers are typedef, extern, static, auto, and register. An object declared with linkage, or with the specifier static, has a static storage duration: the storage is reserved, andinitialization is performed, prior to the program startup; object exists, and retains its last-stored value, throughout the program execution. An object declared with no linkage, without the specifierstatic, has automatic storage duration: the storage is reserved on normal entry into the block, in which it is declared, or on jump to a label in the block, or in enclosed block. Initialization is performedonly on a normal entry; the storage is not guaranteed after execution of the block. A declaration of a function, with a block scope, may only have the storage-class specifier extern. A specifier register, suggests that access to object be as fast, as possible. The specifiers auto andregisterm shall not appear in the declaration specifiers of an external declaration.

Types

A type determines the meaning of an object, or a value returned by a function. Type has a top type, which is a declaration specifier of a typedef name, or the type itself. A type name is a declaration for function or object, which omits the identifier, or a typedef name. A typedef name has the same name space, as ordinary identifiers. The declarator has the type specified by declaration-specifiers, as:

typedef declaration-specifiers typedef-name;typedef-name declarator;

The smallest object is an object with type char, which is usually composed of sequence of 8 bits (a unit which may have one of two values, most significant bit is high-order bit), and which represents byte. Such object can store a member of a basic character set (character), as a positive value.

The signed integer types are: signed char, short int, int, and long int. For every signed integer type, there is the unsigned integer type (designated with the keyword unsigned), with the same amount of storage, including the sign. A computation involving unsigned operands, can never overflow. The floating types are: float, double, and long double. void means an empty set of values, it is an incomplete type, and cannot be completed.

The type char, integer types, and floating types, are basic types. The type char, integer types, and enumerated types, are integral types. The integral types, and floating types, are arithmetic types. The arithmetic types, and pointer types, are scalar types. The array types, and structure types, are aggregate types. An array of unknown size, or astructure or union of unknown content, is an incomplete type: it is completed in a later declaration, in the same scope.

The types are compatible, if they are the same. Compatible types are identically qualified. The structure, union, or enumeration types, arecompatible, if they have the same number of members, the same member names, and compatible member types; structure members shall be in the same order; enumeration members shall have the same values. Pointers shall be pointers to compatible types. Functions shall specify compatible return types; parameter type lists, if present, shall agreein the number of parameters, and in use of ellipsis; parameters shall have compatible types. If one declaration has a parameter type list, and the other, what is not a definition, contains an empty identifier list, the parameter list shall not have ellipsis. If one type has a parameter type list, and the other has an identifier list, both shall agree in the number of parameters. Declarations in the same scope, that refer to the same object or function, specify compatible types. A composite type is compatible with two compatible types. If one is an array of known size, composite type is an array of that size. If one is a function with a parameter type list, the composite type is a prototype with parameter type list. If both have parameter type lists, parameter type is the composite type of the corresponding parameters. Identical identifiers inthe same scope, with linkage, shall have a composite type.

A type is qualified, if its top type has a type qualifier; this is meaningful only for lvalues. The type “float *” is “pointer to float”, and the top type is a pointer type; const-qualified version is “float *const”. The type “const float *” is not qualified: it is a pointer to a qualified type. The type “struct tag (*[5]) (float)” is “array of pointer to function returning struct tag”, the top type is array with length five; function has a parameter with the type float. If an attempt was made, to modify object with const-qualified type, or refer to anobject with volatile-qualified type, through a non-volatile lvalue, behavior is undefined. Object with volatile-qualified type, may be modified in unknown ways, or has other unknown side effects. If an array type is qualified, the element type is so qualified.

An object with an integral type, or int bit-field, may be used in expression, where int or unsigned int may be used. If int can represent all values of the original type, the value is converted to int,otherwise to unsigned int (integral promotions). When a floating type is converted to an integral type, the fractional part is discarded. When anintegral type is converted to a floating type, or double is demoted to float, or long double to double or float, and it can be represented inexactly, the result is the nearest higher or lower value(implementation-defined). Operators with operands of arithmetic type, yield common type. In assignment, right operand is converted to the type of the assignment expression. If == or != operand, or second, or third operand of a conditional operator, is a pointer to void, the other operand is converted to a pointer to void. Except for sizeof, or unary & operand, an lvalue with an array type is converted to the pointer to initial member (not lvalue), and a function designator is converted to apointer to function. void expression shall not be converted; if other expression occurs, where void is required, its value, or designator is discarded. A pointer to void may be converted to, or from, pointer to object, or incomplete type. A pointer to a non-qualified type, may be converted to a pointer to qualified type. Null pointer is constant withvalue 0, or its cast to void *; if assigned to, or compared to a pointer, it is converted to a pointer of that type.

( type-name ) expression

This converts expression to the named type: this is cast. The operand has a scalar type, unless type-name is void. A pointer may be convertedto an integral type, and integer to pointer. A pointer to an object or incomplete type, may be converted to a pointer to object or incompletetype, of the same, or less strict alignment. A pointer to a function may be converted to a pointer to function. In arithmetic constant expression, except sizeof operand, the cast only converts arithmetic types to arithmetic types.

Scopes and linkages

An identifier is visible (can be used), only within a region of program, called scope: an outer declaration of an identical identifier, in the samename space, is hidden, until the scope terminates. A label name has a function scope. If a declarator is outside any block, or a list of parameters, the declared identifier has a file scope, which terminates at the end of the translation unit. If a declarator is insidea block, or list of parameter declarations, in a function definition, the declared identifier has a block scope, which terminates at } which closes the block. If a declarator is in a list of parameter declarations, in function prototype, the declared identifier has a function prototype scope, which terminates at the end of the functiondeclarator. A structure, union and enumeration tags have scope, which begins after an appearance of the tag in a declaration. An enumeration constant has a scope, which begins after appearance in the enumerator list. Any other identifier has a scope, which begins after the completion of its declarator.

In a set of translation units, and libraries, which constitutes a program, each instance of an identifier with an external linkage, and within a translation unit, each instance of an identifier with an internal linkage, denotes the same object, or function. A declaration of an object, with a file scope, and initializer, is called an external definition, there may only be one external definition for an identifier. If a declaration of an identifier for an object, or function, has a filescope, and a specifier static, the identifier has an internal linkage. If a declaration contains the specifier extern, the identifier has the same linkage, as a visible declaration of it, with file scope, or an external linkage, if there is no such declaration. If a declaration of a function has no storage-class specifier, the linkage is determined, as if it had the specifier extern. If a declaration of an object, has a file scope, and no storage-class specifier, the linkage is external. An identifier other than object, function, function parameter, or an object inside a block without the specifier extern, has no linkage, it shall only be declared once, and its type shall be complete. A tentativedefinition is a declaration of an object, with a file scope, without an initializer, and with no storage-class specifier, other than static; it must declare a complete type, if it has an internal linkage.

Constants

A decimal integer constant begins with a nonzero digit, and consists of a sequence of decimal digits. An octal constant consists of the prefix 0, optionally followed by a sequence of digits 0 through 7. A hexadecimal constant consists of the prefix 0x or 0X followed by a sequence of decimal digits, and letters a, or A, through f, or F, withvalues 10 through 15. The first digit is most significant. Type of an integer constant is the first in the list, in which its value can be represented–decimal: int, long int, unsigned long int; octal or hexadecimal: int, unsigned int, long int, unsigned long int; suffixed by u or U: unsigned int, unsigned long int; suffixed by l or L: long int, unsigned long int; suffixed by both u or U, and l or L: unsigned long int.

A floating constant has a value part, which may be followed by an exponent part, and a suffix. The components of a value part, may include a digit sequence, representing the whole-number part, followed by period (.), followed by a digit sequence, representing the fraction part. The components of an exponent part, are e or E, followed by an exponent, consisting of an optionally signed digit sequence. The Exponent indicates the power of 10, by which the value part is to be scaled. Unsuffixed floating constant has a type double. If suffixed by a letter f or F, it has a type float. If suffixed by a letter l or L, it has a type long double.

An integer character constant is a sequence of multibyte characters, enclosed in single-quotes, as ‘x’, or ‘ab’. It has a type int, the value is a representation of a mapped character. A wide character constant is the same, prefixed by L, with a type wchar-t, its value corresponds to a sequence of bytes, representing a member of an extended character set, as defined by locale: for example, L’1234′ always specifies the combination of values 0123 and ‘4’. A single-quote ‘ can be representedby ‘, ” by “, ? by ?, by , form feed by f, new-line by n, carriage return by r, horizontal tab by t, vertical tab by v, nullcharacter by , octal integer by octal digits, and hexadecimal integer by x hexadecimal digits, the escape sequences a and b are implementation-defined.

A character string literal is a sequence of zero, or more multibyte characters, enclosed in double-quotes. It has a static storage duration,and a type “array of char”. A wide string literal is the same, prefixed by L, with a type “array of wchar-t”, and it is initialized with wide characters. The same considerations apply to an element in a string literal, as if it was a character constant. The adjacent string literalsare concatenated into a single one, null character is appended. “x12” “3” produces a string literal, containing characters x12 and ‘3’.

A constant expression is evaluated during translation, to a constant, and may be used in any place in which a constant may be. It shall notcontain assignment, increment, decrement, function call, or comma operators, except in sizeof operand. An arithmetic constant expression has an arithmetic type, operands shall be integer, floating,enumeration, or character constants, or sizeof expressions. The floating operands in an integral constant expression, shall be immediate operandsof casts. An address constant is a pointer to a static lvalue, or to a function designator, created by unary & operator, or by expression witharray, or function type; array subscript [], member-access . and ->, address & and indirection * operators, and pointer casts may be used.

Initialization

An Initializer specifies the initial value, stored in an object; the unnamed structure or union members are ignored. There shall be no more initializers, than there are objects to be initialized. The type of entity to be initialized, shall be object, or array of unknown size. The expressions in initializer for static object, or for aggregate, orunion, shall be constant expressions. If a static object is not initialized explicitly, it is initialized implicitly, as if the members with an arithmetic type, were assigned 0, and the members with a pointer type, were assigned a null pointer.

An initializer for scalar, shall be an expression, conversions as for assignment apply. An initializer for an automatic structure, or union, may be expression with compatible structure, or union type. Array of type char, or wchar-t, may be initialized by string literal: successive codes, including the terminating zero-valued code, initialize members.Otherwise an initializer for aggregate type, shall be brace-enclosed list of initializers for members, or for first member of a union. If an initializer of a subaggregate, or contained union, begins with a left brace, the enclosed initializers, and matching right brace, initialize members of the subaggregate, or a first member of the contained union. Otherwise, enough initializers are taken for members of the first subaggregate, or the first member of contained union. If there are fewer initializers, than members, the remainder is initialized implicitly, asstatic objects. Size of the array of unknown size, is determined by the number of initializers.

Structures, unions, and enumerations

A structure type declares sequentially allocated set of members. A union type declares overlapping set of members. A member may have a name, and a complete object type. The declaration list in the declarationspecifier declares a new type, which is incomplete until } which terminates the list. A member with type int, unsigned, or signed int, which consists of specified number of bits, is a bit-field, its width is nonnegative integral constant, preceded by colon. If the width is zero, the declaration has no declarator. A bit-field, declared with only acolon and width, is unnamed. An unnamed bit-field with width 0, indicates that no further bit-field is to be packed into unit. If a space remains, the next bit-field in a structure, shall be packed intothe same storage unit. Whether a bit-field may overlap the adjacent units, the order of allocation within a unit (high-order to low, or vice versa), and whether the high-order bit is sign, is implementation-defined; alignment of a unit is unspecified. A pointer to a structure, points to the initial member or unit. There may be unnamed holes in the structure, or unnamed padding at the end of the structure or union, for the alignment in an array. The size of a union is sufficient to contain the largest member; pointer to a union, points toeach member.

The first operand of . operator is a structure or union, the second designates a member. The first operand of -> operator is a pointer to astructure or union, and the second designates a member. If a union contains structures, which have compatible types for a sequence of initial members, it is permitted to inspect a common initial part ofthem. If f is a function, returning a structure, or union, and x is its member, f().x is valid, but not an lvalue.

An enumeration type declares a set of named constants, with type int. An enumerator with = defines enumeration constant. If the first enumeratorhas no =, its enumeration constant is 0. Each enumerator with no = defines an enumeration constant, by adding 1 to the previous one.

Pointers and arrays

T * type-qualifier-list<opt> identifier

In this declaration the type for identifier is “pointer to T”, for each type qualifier, the identifier is so qualified pointer. A pointer is an object, whose value is a reference to an entity of the referenced type, which may be a function, an object, or incomplete type. A pointer to void has the same representation and alignment, as a pointer to char.

The result of an unary address-of operator & is a pointer to an object or function, the operand is a function designator, or lvalue, which is not a bit-field or register object. An unary * operator denotes indirection, the operand has a pointer type. If it points to a function, the result is a function designator; if it points to an object, the result is a lvalue, designating an object.

T identifier [ constant-expression<opt> ]

In this declaration the type for identifier is “array of T”. An integral constant, with a value greater than zero, specifies size. An array type declares a contiguously allocated set of objects, with a particular member type. An expression, followed by an expression in square brackets [] designates a member of array, E1 [E2] is identical to (*(E1 + (E2))), and designates E2-th member of E1, counting from zero. Successive subscript operators designate a member of a multi-dimensional array.

Functions

T identifier ( parameter-type-list )

In this declaration (prototype), the type for identifier is “function returning T”. The return type of a function, shall not be a function or array. A parameter type list specifies types, and may declare identifiers for parameters. If the list terminates with ellipsis ( , …), no information is supplied about the parameters after a comma; thedefault argument promotions are performed on the trailing arguments. void as an only item in the list, means that the function has no parameters. A storage-class specifier in parameter declaration isignored, except in definition. An empty parameter type list in a definition, means that the function has no parameters; an empty list in other declarations, means that no information is supplied.

T<opt> function-name ( parameter-type-list )declaration-list<opt>compound-statement

If a function definition includes a parameter type list, parameter declarator shall include identifier (except a single parameter of type void), and no declaration list shall follow. Otherwise, only the identifiers named in a list shall be declared in a declaration list, with no storage-class specifier other than register, and with no initialization.Parameter which is not declared, has type int. Storage-class specifier may be extern or static.

A function call is an expression followed by parentheses (), containing a possibly empty, comma-separated list of expressions. The expressiondenotes the called function, the list of expressions specifies the arguments, which have an object type. If a called function has no prototype, integral promotions are performed, and float arguments arepromoted to double. On an entry to a function, each argument is converted to the type of its parameter, as if by assignment to the parameter; an array expressions, and function designators, are convertedto pointers. If an identifier, which precedes a parenthesized argument list, gets no other type, the identifier is declared, as if there was a visible declaration “extern int identifier ()”.

A function called at program startup, in a hosted environment, is named main. If parameter argc (argc and argv may have other names), is greater than zero, argv [0] through argv [argc – 1] contain pointers to strings, which are program parameters. argv [0] is a program name, argv [argc] is a null pointer. Return from an initial call to main, isequivalent to calling exit, with the value returned by main, as argument.

Operators

The result of an unary + is the value of the operand; of unary – negative of operand; of ~ a bitwise complement of operand (a bit is setonly if the corresponding bit in the operand is not set). The result of logical negation ! is 0 only if operand is unequal to 0. The result of a postfix ++ is the value of operand, the operand is incremented (1 is added), after the result is obtained. A postfix — is similar, but the operand is decremented (1 is subtracted). The operand of the prefix ++ is incremented, the result is the new value. Prefix — is similar, but the operand is decremented. The operand of an unary + or – hasarithmetic type; of ~ integral type; of ! scalar type; of increment and decrement, a modifiable scalar lvalue. sizeof yields size in bytes, withtype size-t, of an expression or of a parenthesized type name; size is determined from type, and operand is not evaluated; shall not be applied to a function, to an incomplete type, or to a bit-field lvalue.

The result of binary + is a sum of operands; of binary – a difference resulting from subtraction of the second operand from the first. When an integral expression is added to, or subtracted from a pointer, the integral value is first multiplied by the size of an object pointed to; the result has the type of the pointer operand. When pointers to members of the same array are subtracted, the difference is divided by the size of a member; the result is the difference of the subscripts of members, with type ptrdiff-t. The operands have arithmetic type, or one operand (left in case of subtraction) is a pointer to an object, and the other has an integral type. For subtraction, the operands may be pointers to the compatible object types.

The result of binary * is a product of operands; of / quotient from the division of the first operand by the second; of % remainder. When integers are divided, and the division is inexact: if the operands are positive, the result of / is the largest integer less than algebraic quotient, and the result of % is positive; If one operand is negative, whether the result of / is the largest integer less than, or the smallest integer greater than algebraic quotient, is implementation-defined, as is the sign of the result of %. The Operandshave arithmetic type, the operands of % have integral type.

The result of a bitwise shift E1 << E2, is E1 left-shifted E2 bit positions; the vacated bits are filled with zeros. If E1 has the type unsigned long, the result is E1 multiplied by 2, raised to the power E2, reduced modulo ULONG-MAX + 1. The result of E1 >> E2, is E1 right-shifted E2 bit positions. If E1 has nonnegative value, the resultis the integral part of the quotient of E1, divided by 2, raised to the power E2. If E1 has a negative value, the result is implementation-defined. The operands have integral type, the result has the type of the left operand.

Relational operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to), yield 1, if relation istrue, and 0, if not; the result has type int. The operands have arithmetic type, are pointers to the compatible object types, or incomplete types. When pointers are compared, and the objects pointed toare members of the same aggregate, the pointers to structure members what were declared later, and the pointers to array elements with larger subscript values, compare higher. Pointers to members of the same union, compare equal. If the objects pointed to, are not members of the same aggregate or union, the result is undefined; except if P points tothe last member of an array and Q points to a member of the same array, P + 1 compares higher than Q. == (equal to), and != (not equal to), are similar to the relational operators, except for lower precedence. If pointers point to the same object, function, or incomplete type, they compare equal.

The result of binary & is bitwise AND of the operands (each bit is set only if the corresponding bits in both operands are set). The result of ^ is bitwise exclusive OR (a bit is set only if one of the corresponding bits in both operands is set). The Result of | is bitwise inclusive OR of the operands (a bit is set, if one, or both of corresponding bits in the operands, are set). The operands have integral type.

An operator && yields, 1 if both operands are unequal to 0, otherwise it yields 0. If the first operand is equal to 0, the second operand is not evaluated. || yields 1, if either of the operands is unequal to 0, otherwise it yields 0. If the first operand is unequal to 0, the second operand is not evaluated. The result has type int; the operands have scalar type.

An operator = (assignment), stores a value in an object, designated by the left operand (modifiable lvalue). An assignment expression has the value of the left operand, after assignment, but is not an lvalue; its type is an unqualified version of the type of the left operand. The order of evaluation of the operands is unspecified. The value of theright operand, replaces the value of the left operand. The operands have arithmetic type, or are pointers to the compatible types, or the left operand has a structure or union type, compatible with the type of the right operand, or one operand is a pointer to an object or incomplete type, and the other is a pointer to void, or the left operandis a pointer, and the right operand is a null pointer. A compound assignment E1 op = E2, differs from the expression E1 = E1 op E2, in that E1 is evaluated only once. For += and -=, either left operand is a pointer to an object, and the right operand has an integral type, or both operands have arithmetic type.

expression ? expression : expression

The first operand of a conditional operator, is evaluated; the second operand is evaluated only if the first compares unequal to 0; the third operand is evaluated only if the first operand compares equal to 0; the result is the value of the evaluated second operand, or third operand. The first operand has a scalar type. Both the second and the thirdoperands have an arithmetic type, compatible structure or union types, void type, are pointers to the compatible types, or one is a pointer, and the other is a null pointer, or one is a pointer to an object or incomplete type, and the other is a pointer to void. If both operands have a structure or union type or void type, the result has that type. If both are pointers to compatible types, the result has a composite type. If one operand is a null pointer, the result has the type of the other operand.

The left operand of a comma operator, is evaluated as a void expression, then the right operand is evaluated, the result has its type and value.Where comma is a punctuator, the comma operator shall be used within a parenthesized expression, or in the second expression of a conditional operator.

Statements

if ( expression ) statementif ( expression ) statement else statement

The first statement is executed if the expression is unequal to 0, the second statement is executed if it is equal to 0; the expression has a scalar type. If the first statement is reached via a label, the second is not executed, else is associated with a preceding elseless if, in the closest block.

switch ( expression ) statementcase constant-expression : statementdefault : statement

If a case label in a statement called switch body, matches the expression, the control jumps to the statement which follows the matched label; otherwise, if there is a default label, the control jumps to that label; otherwise no part of the switch body is executed. The integral constant expression in a case label, is converted to a promoted type ofthe controlling integral expression. Two case expressions in a switch statement, shall not have the same value. There is at most one default label. The labels are accessible only within the closest switch statement.

while ( expression ) statementdo statement while ( expression ) ;for ( expression<opt> ; expression<opt> ; expression<opt> ) statement

An iteration statement causes a statement called a loop body, to be executed repeatedly, until the controlling scalar expression compares equal to 0. In a while statement, the evaluation of the expression takes place before, in do statement after each execution of the loop body.

goto identifier; /* label in current function */identifier: statement /* declares label name */continue; /* appears only in loop body */break; /* appears only in switch or loop body */return expression<opt>;

A goto statement causes a jump to the statement prefixed by the named label. a break statement terminates the execution of the closest switchor iteration statement. A continue statement causes a jump to the end of the closest loop body.

A return statement terminates the execution of the current function, and returns the control to its caller. A return with an expression shall notappear in a function with type void; the expression is converted, and assigned to the function call expression. Reaching } which terminates a function is equivalent to executing a return statement without an expression.

An expression statement is evaluated as a void expression. A null statement (only a semicolon) performs no operations.

Preprocessing directives

# define identifier replacement-list new-line# undef identifier new-line

This defines an object-like macro, which causes each subsequent instance of a macro name, to be replaced by the replacement-list; may be redefined by another object-like macro definition, with an identicalreplacement list. A macro definition lasts until the corresponding #undef directive is encountered, or until the end of a translation unit.

# define macro-name ( identifier-list<opt> ) replacement-list new-line

This defines a function-like macro; may be redefined by another such definition, which has the same number and spelling of the parameters, and an identical replacement list. The parameters in an optional identifier list, shall be uniquely declared within their scope. Each subsequent instance of the macro name, followed by ( is replaced by thereplacement list (invocation). The number of arguments agree with the number of parameters, and ) terminates the invocation. The replacement lists are identical, if the tokens have the same number, ordering, spelling, and white-space; all white-space separations are identical. A white-space preceding, or following the replacement list, is not a partof it. If a parameter is preceded by # or preceded or followed by ##, it is replaced by the corresponding argument’s sequence. Order ofevaluation of # and ## is unspecified, ## shall not occur at the beginning, or at the end of the replacement list.

Predefined macro names are the line number of the current source line –LINE–, the name of the source file (string literal) –FILE–, the date of translation of the source file (string literal), the time of translation of the source file (string literal). These are not the subjects of #define or #undef, and begin with an underscore, followed byan upper-case letter, or underscore.

# include < h-char-sequence > new-line# include ” q-char-sequence ” new-line

This searches the implementation-defined places, for a header (source file), identified by a sequence between < and >, and causes a replacement of that directive by the contents of the header. For the second form, the source file is searched for in an implementation-defined manner; if it fails, the directive is reprocessed as the first form. If characters ‘, , , or /* occur in the sequence,the behavior is undefined. The inclusion may appear in the included source file.

# if constant-expression new-line group<opt># elif constant-expression new-line group<opt># ifdef identifier new-line group<opt># ifndef identifier new-line group<opt>defined identifierdefined ( identifier )

Directives #if and #elif check whether the integral expression evaluates to nonzero; the expression contains no cast, and may contain the expressions “defined”, which evaluate to 1, if the identifier is defined as a macro name, and to 0 if not. #ifdef and #ifndef are equivalent to #if defined and #if !defined. The first group, whose condition evaluates to true (nonzero), is processed. If none of the conditions evaluates to true, and there is an #else directive, the group controlledby #else is processed. Lacking the #else directive, all groups until #endif are skipped.

# line digit-sequence “char-sequence<opt>”# error preprocessing-tokens<opt># pragma preprocessing-tokens<opt>

Directive #line causes the implementation to behave, as if the sequence of the source lines which follows, begins with the source line, which has the line number, specified by the digit sequence; a presumed name of the source file shall be changed to the char-sequence. #error produces a diagnostic message, which includes a sequence of preprocessing tokens. #pragma causes the implementation to behave in an implementation-defined manner.


Note: if anyone cares about this page, please post. Otherwise it will be deleted in 2005.

TakeDown.NET -> “C89