United States

Compaq C

# Compaq C
Language Reference Manual

Previous | Contents | Index

1. A series of `case` statements is used to increment separate counters depending on the character encountered.
2. The `break` statement causes control to return to the `while` loop. Control is passed to the `while` loop if the value of `ch` does not match any of the `case` constant expressions.

Without the `break` statements, each `case` would drop through to the next.

If variable declarations appear in the compound statement within a `switch` statement, initializers on `auto` or `register` declarations are ineffective. However, initializations within the statements following a `case` are effective. Consider the following example:

    switch (ch)
       {
          int nx = 1;          /* Initialization ignored            */
          printf("%d", n);     /* This first printf is not executed */
          case 'a' :
           { int n = 5;        /* Proper initialization occurs      */
             printf("%d", n);
             break; }
          case 'b' :
             { break; }
          default :
             { break; }
       }

In this example, if `ch == 'a'` , then the program prints the value 5. If the variable equals any other letter, the program prints nothing because the initialization occurs outside of the `case` label, and statements outside of the `case` label are ineffective.

# 7.6 Iteration Statements

An iteration statement, or loop, repeatedly executes a statement, known as the loop body, until the controlling expression is false (0). The control expression must have a scalar type.

The `while` statement evaluates the control expression before executing the loop body (see Section 7.6.1).

The `do` statement evaluates the control expression after executing the loop body; at least one execution of the loop body is guaranteed (see Section 7.6.2).

The `for` statement executes the loop body based on the evaluation of the second of three expressions (see Section 7.6.3).

## 7.6.1 The while Statement

The `while` statement evaluates a control expression before each execution of the loop body. If the control expression is true (nonzero), the loop body is executed. If the control expression is false (0), the `while` statement terminates. The `while` statement has the following syntax:

`while ( expression ) statement`

Consider the following `while` statement:

    n = 0;
    while (n < 10)
       {
          a[n] = n;
          n++;
       }

This statement tests the value of `n` ; if `n` is less than 10, it assigns `n` to the nth element of the array `a` and then increments `n` . The control expression (in parentheses) is then evaluated; if true (nonzero), the loop body is executed again; if false (0), the `while` statement terminates. If the statement `n++` were missing from the loop body, this `while` statement would never terminate. If the statement `n = 0` were replaced by the statement `n = 10` , the control expression is initially false (0), and the loop body is never executed.

## 7.6.2 The do Statement

The `do` statement evaluates the control expression after each execution of the loop body. The `do` statement has the following syntax:

`do statement while ( expression ) ;`

The loop body is executed at least once. The control expression is evaluated after each execution of the loop body. If the control expression is true (nonzero), the statement is executed again. If the control expression is false (0), the `do` statement terminates.

## 7.6.3 The for Statement

The `for` statement evaluates three expressions and executes the loop body until the second controlling expression evaluates to false (0). The `for` statement is useful for executing a loop body a specified number of times. The `for` statement has the following syntax:

`for ( expression-1opt ; expression-2opt ; expression-3opt) statement`

The `for` statement is equivalent to the following code:

`expression-1;`

`while ( expression-2 ) { statement expression-3 ; }`

The `for` statement executes the loop body zero or more times. Semicolons (;) are used to separate the control expressions. A `for` statement executes the following steps:

1. expression-1 is evaluated once before the first iteration of the loop. This expression usually specifies the initial values for variables used in the loop.
2. expression-2 is any scalar expression that determines whether to terminate the loop. expression-2 is evaluated before each loop iteration. If the expression is true (nonzero), the loop body is executed. If the expression is false (0), execution of the `for` statement terminates.
3. expression-3 is evaluated after each iteration.
4. The `for` statement executes until expression-2 is false (0), or until a jump statement, such as `break` or `goto` , terminates execution of the loop.

Any of the three expressions in a `for` loop can be omitted:

- If expression-2 is omitted, the test condition is always true; that is, the `while` loop equivalent becomes `while(1)` . This is an infinite loop. For example:

      for (i = 0;  ;i++)
          statement;

  Infinite loops can be terminated with a `break` , `return` , or `goto` statement within the loop body.
- If either expression-1 or expression-3 is omitted from the `for` statement, the omitted expression is evaluated as a `void` expression and is effectively dropped from the expansion. For example:

      n = 1;
      for ( ; n < 10; n++)
         func(n);

  In this example, `n` is initialized before the `for` statement is executed.

In relaxed ANSI C mode, the first clause of the `for` statement can be a declaration whose scope includes the remaining clauses of the `for` header and the entire loop body. This is normally used to declare and initialize a local loop control variable. For example:

    for (int i=0; i<10; i++)
        printf("%d\n", i);

# 7.7 Jump Statements

Jump statements cause an unconditional jump to another statement elsewhere in the code. They are used primarily to interrupt `switch` statements and loops.

The jump statements are the `goto` statement, the `continue` statement, the `break` statement, and the `return` statement, which are discussed in the following sections.

## 7.7.1 The goto Statement

The `goto` statement unconditionally transfers program control to a labeled statement, where the label identifier is in the scope of the function containing the `goto` statement. The labeled statement is the next statement executed. The `goto` statement has the following syntax:

`goto identifier;`

Care must be taken when branching into a block by using the `goto` statement, because storage is allocated for automatic variables declared within a block when the block is activated. When a `goto` statement branches into a block, automatic variables declared in the block are not initialized.

## 7.7.2 The continue Statement

The `continue` statement passes control to the end of the immediately enclosing `while` , `do` , or `for` statement. The `continue` statement has the following syntax:

`continue;`

The `continue` statement is equivalent to a `goto` statement within an iteration statement that passes control to the end of the loop body. For example, the following two loops are equivalent:

    while(1)                           while(1)
    {                                  {
       .                                  .
       .                                  .
       .                                  .
      goto label_1;                     continue;
       .                                  .
       .                                  .
       .                                  .
      label_1:
       ;                                  ;
     }                                  }

The `continue` statement can be used only in loops. A `continue` inside a `switch` statement that is inside a loop causes continued execution of the enclosing loop after exiting from the body of the `switch` statement.

## 7.7.3 The break Statement

The `break` statement terminates execution of the immediately enclosing `while` , `do` , `for` , or `switch` statement. Control passes to the statement following the loop body (or the compound statement of a `switch` statement). The `break` statement has the following syntax:

`break;`

See Example 7-1 which uses a `break` statement within a `switch` statement.

## 7.7.4 The return Statement

The `return` statement terminates execution of a function and returns control to the calling function, with or without a return value. A function may contain any number of `return` statements. The `return` statement has the following syntax:

`return expressionopt;`

If present, the expression is evaluated and its value is returned to the calling function. If necessary, its value is converted to the declared type of the containing function's return value.

A `return` statement with an expression cannot appear in a function whose return type is `void` . For more information about the `void` data type and function return types, see Sections 3.5 and 3.4.1.

If there is no expression and the function is not defined as `void` , the return value is undefined. For example, the following `main` function returns an unpredictable value to the operating system:

    main ( )
      {
       return;
      }

Reaching the closing brace that terminates a function is equivalent to executing a `return` statement without an expression.

# Chapter 8
Preprocessor Directives and Predefined Macros

The C preprocessor provides the ability to perform macro substitution, conditional compilation, and inclusion of named files. Preprocessor directives, lines beginning with `#` and possibly preceded by white space, are used to communicate with the preprocessor.

The following sections describe the preprocessor directives and operators available with the Compaq C compiler:

- The `#define` and `#undef` directives, and the `#` and `##` operators ( Section 8.1)
- The `#if` , `#ifdef` , `#ifndef` , `#else` , `#elif` , and `#endif` directives, and the `defined` operator ( Section 8.2)
- The `#include` directive ( Section 8.3)
- The `#line` directive ( Section 8.4)
- The `#pragma` directive ( Section 8.5)
- The `#error` directive ( Section 8.6)
- The null directive ( `#` ) ( Section 8.7)

Preprocessor directives are independent of the usual scope rules; they remain in effect from their occurrence until the end of the compilation unit or until their effect is canceled.

See Section 8.2 for more information about conditional compilation. See your platform-specific Compaq C documentation for implementation-defined information about preprocessor directives.

The ANSI standard allows only comments as text following a preprocessing directive. The Compaq C compiler issues a warning if this syntax rule is violated in all modes but the strict ANSI mode, in which it issues an error message.

# 8.1 Macro Definition (#define and #undef)

The `#define` directive specifies a macro identifier and a replacement list, and terminates with a new-line character. The replacement list, a sequence of preprocessing tokens, is substituted for every subsequent occurrence of that macro identifier in the program text, unless the identifier occurs inside a character constant, a comment, or a literal string. The `#undef` directive is used to cancel a definition for a macro.

A macro definition is independent of block structure, and is in effect from the `#define` directive that defines it until either a corresponding `#undef` directive or the end of the compilation unit is encountered.

The `#define` directive has the following syntax:

`#define identifier replacement-list newline`

`#define identifier ( identifier-listopt ) replacement-list newline`

`#define identifier ( ... ) replacement-list newline`

`#define identifier ( identifier-list, ... replacement-list newline`

If the replacement-list is empty, subsequent occurrences of the identifier are deleted from the source file.

The first form of the `#define` directive is called an object-like macro. The last three forms are called function-like macros.

The `#undef` directive has the following syntax:

`#undef identifier newline`

This directive cancels a previous definition of the identifier by `#define` . Redefining a macro previously defined is not legal, unless the new definition is precisely the same as the old.

The replacement list in the macro definition, as well as arguments in a function-like macro reference, can contain other macro references. Compaq C does not limit the depth to which such references can be nested.

For a given macro definition, any macro names contained in the replacement list are themselves replaced by their currently specified replacement lists. If a macro name being defined is contained in its own replacement list or in a nested replacement list, it is not replaced. These nonreplaced macro names are then no longer available for further replacement, even if they are later examined in contexts in which they would otherwise be replaced.

The following example shows nested `#define` directives:

    /*  Show multiple substitutions and listing format. */

    #define  AUTHOR  james + LAST

    main()
    {
       int writer,james,michener,joyce;

       #define LAST michener
       writer = AUTHOR;
       #undef LAST
       #define LAST joyce
       writer = AUTHOR;
    }

After this example is compiled with the appropriate options to show intermediate macro expansions, the following listing results:

        1            /* Show multiple substitutions and listing format. */
        2
        3            #define AUTHOR james + LAST
        4
        5            main()
        6            {
        7              int writer, james, michener, joyce;
        8
        9              #define LAST michener
       10              writer = AUTHOR;
       10.1                     james + LAST
       10.2                     michener
       11              #undef LAST
       12              #define LAST joyce
       13              writer = AUTHOR;
       13.1                     james + LAST
       13.2                     joyce
       14            }

On the first pass, the compiler replaces the identifier `AUTHOR` with the replacement list `james + LAST` . On the second pass, the compiler replaces the identifier `LAST` with its currently defined replacement list value. At line 9, the replacement list value for `LAST` is the identifier `michener` , so `michener` is substituted at line 10. At line 12, the replacement list value for `LAST` is redefined to be the identifier `joyce` , so `joyce` is substituted at line 13.

The `#define` directive may be continued onto subsequent lines if necessary. To do this, end each line to be continued with a backslash (\) immediately followed by a new-line character. The backslash and new-line characters do not become part of the definition. The first character in the next line is logically adjacent to the character that immediately precedes the backslash. The backslash/newline as a continuation sequence is valid anywhere. However, comments within the definition line can be continued without the backslash/newline.

If you plan to port programs to and from other C implementations, take care in choosing which macro definitions to use within your programs, because some implementations define different macros than others.

## 8.1.1 Object-Like Form

A preprocessing directive of the following form defines an object-like macro that causes each subsequent occurrence of the macro name to be replaced by the replacement list:

    #define identifier replacement-list newline

An object like macro may be redefined by another `#define` directive provided that the second definition is an object-like macro definition and the two replacement lists are identical. This means that two files, each with a definition of a certain macro, must be consistent in that definition.

The object-like form of macro definition defines a descriptive name for a frequently used token. A common use of the directive is to define the end-of-file ( `EOF` ) indicator as follows:

    #define  EOF  (-1)

Previous | Next | Contents | Index

privacy and legal statement