HP C/iX Reference Manual HP 3000 MPE/iX Computer Systems Edition 3 Manufacturing Part Number: 31506-90011 E0499 U.S.A.
Notice The information contained in this document is subject to change without notice. Hewlett-Packard makes no warranty of any kind with regard to this material, including, but not limited to, the implied warranties of merchantability or fitness for a particular purpose. Hewlett-Packard shall not be liable for errors contained herein or for direct, indirect, special, incidental or consequential damages in connection with the furnishing or use of this material.
Introduction 1 Introduction HP C originates from the C language designed in 1972 by Dennis Ritchie at Bell Laboratories. It descended from several ALGOL-like languages, most notably BCPL and a language developed by Ken Thompson called B. Work on a standard for C began in 1983. The Draft Proposed American National Standard for Information SystemsProgramming Language C was completed and was approved by the Technical Committee X3J11 on the C Programming Language in September, 1988.
Introduction ANSI Mode ANSI Mode Unless you are writing code that must be recompiled on a system where ANSI C is not available, it is recommended that you use the ANSI mode of compilation for your new development. It is also recommended that you use ANSI mode to recompile existing programs after making any necessary changes.
Lexical Elements 2 Lexical Elements This chapter describes the lexical elements of the C language, using Backus-Naur form.
Lexical Elements Tokens Tokens A token is the smallest lexical element of the C language.
Lexical Elements Syntax Syntax token := keyword identifier constant string-literal operator punctuator Chapter 2 9
Lexical Elements Description Description The compiler combines input characters together to form the longest token possible when collecting characters into tokens. For example, the sequence integer is interpreted as a single identifier rather than the reserved keyword int followed by the identifier eger. A token cannot exceed 509 characters in length. Consecutive source code lines can be concatenated together using the backslash (\) character at the end of the line to be continued.
Lexical Elements Keywords Keywords The following keywords are reserved in the C language. You cannot use them as program identifiers. Type them as shown, using lowercase characters.
Lexical Elements Identifiers Identifiers An identifier is a sequence of characters that represents an entity such as a function or a data object.
Lexical Elements Identifiers Finally, identifiers cannot have the same spelling as reserved words. For example, int cannot be used as an identifier because it is a reserved word. INT is a valid identifier because it has different case letters. Identifier Scope The scope of an identifier is the region of the program in which the identifier has meaning. There are four kinds of scope: 1.
Lexical Elements Identifiers If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern. If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external. The following identifiers have no linkage: • An identifier declared to be anything other than an object or a function. • An identifier declared to be a function parameter.
Lexical Elements Identifiers block scope. At location A, identifier i is declared. Its scope continues until the end of the block in which it is defined (point G). References to i at location B refer to an integer object. At point C, another identifier is declared. The previous declaration for i is hidden by the new declaration until the end of the block in which the new i is declared. References to the identifier i result in references to a floating-point number (point D).
Lexical Elements Identifiers functions, typedef names, and enumeration constants. Conceptually, the macro prepass occurs before the compilation of the translation unit. As a result, macro names are independent from all other names. Use of macro names as ordinary identifiers can cause unwanted substitutions. Types The type of an identifier defines how the identifier can be used. The type defines a set of values and operations that can be performed on these values.
Lexical Elements Identifiers 2. Arrays — Arrays are collections of homogeneous objects. C arrays can be multidimensional with conceptually no limit on the number of dimensions. c. Unions — Unions, like structures, can hold different types of objects. However, all members of a union are "overlaid"; that is, they begin at the same location in memory. This means that the union can contain only one of the objects at any given time.
Lexical Elements Constants Constants A constant is a primary expression whose literal or symbolic value does not change. Syntax constant := floating-constant integer-constant enumeration-constant character-constant Description Each constant has a value and a type. Both attributes are determined from its form. Constants are evaluated at compile time whenever possible. This means that expressions such as 2+8/2 are automatically interpreted as a single constant at compile time.
Lexical Elements Constants NOTE Suffixes in floating-constants are available only in ANSI mode. Description A floating constant has a value part that may be followed by an exponent part and a suffix specifying its type. The value part may include a digit sequence representing the whole-number part, followed by a period (.), followed by a digit sequence representing the fraction part. The exponent includes an e or an E followed by an exponent consisting of an optionally signed digit sequence.
Lexical Elements Integer Constants Integer Constants Integer constants represent integer values.
Lexical Elements Integer Constants Description An integer constant begins with a digit, but has no period or exponent part. It may have a prefix that specifies its base (decimal, octal, or hexadecimal) and suffix that specifies its type. The size and type of integer constants are described in Chapter 9, HP C/iX Implementation Topics. Octal constants begin with a zero and can contain only octal digits.
Lexical Elements Enumeration Constants Enumeration Constants Enumeration constants are identifiers defined to have an ordered set of integer values. Syntax enumeration-constant := identifier Description The identifier must be defined as an enumerator in an enum definition. Enumeration constants are specified when the type is defined. An enumeration constant has type int.
Lexical Elements Character Constants Character Constants A character constant is a constant that is enclosed in single quotes.
Lexical Elements Character Constants lowercase x and any number of hexadecimal digits. It is terminated by any non-hexadecimal characters. The digits of the escape sequences are converted into a single 8-bit character and stored in the character constant at that point. For example, the following character constants have the same value: 'A' '\101' '\x41' They all represent the decimal value 65. Character constants are not restricted to one character; multi-character character constants are allowed.
Lexical Elements Character Constants Examples 'a' '\n' '\?' '7' '\0' '\101' Chapter 2 represents represents represents represents represents represents the letter a, the value 97 the newline character, the value 10 a question mark, the value 63 the character 7, the value 55 the null character, the value 0 the letter A, the value 65 25
Lexical Elements String Literals String Literals A string literal is a sequence of zero or more characters enclosed in double quotation marks.
Lexical Elements String Literals Character string literals that are adjacent tokens are concatenated into a single character string literal. A null character is then appended. Similarly, adjacent wide string literal tokens are concatenated into a single wide string literal to which a code with value zero is then appended. It is illegal for a character string literal token to be adjacent to a wide string literal token.
Lexical Elements Operators Operators An operator specifies an operation to be performed on one or more operands. Syntax operator := One selected from the set Description Operator representations may require one, two, or three characters. The compiler matches the longest sequence to find tokens. For example, is parsed as if it had been written which results in a syntax error.
Lexical Elements Punctuators Punctuators A punctuator is a symbol that is necessary for the syntax of the C language, but performs no runtime operation on data and produces no runtime result. Syntax punctuator := One selected from: [ ] ( ) { } * , : = ; # ... Description Some punctuators are the same characters as operators. They are distinguished through the context of their use. Example #include
Lexical Elements Comments Comments You can include comments to explain code in your program by enclosing the text with /* and */ characters. If the /* character sequence is located within a string literal or a character constant, the compiler processes them as "normal" characters and not as the start of a comment. You cannot nest comments. To comment blocks of code, enclose the block within the #if and #endif statements, as shown below: #if 0 . . code . .
Data Types and Declarations 3 Data Types and Declarations In C, as in many other programming languages, you must declare identifiers before you can use them. The declarable entities in C are objects; functions; tags and members of structures, unions, and enumerated types; and typedef names. This chapter describes declarations, type specifiers, storage-class specifiers, structure and union specifiers, enumerations, declarators, type names, and initialization.
Data Types and Declarations Program Structure Program Structure A translation unit consists of one or more declarations and function definitions. Syntax translation-unit ::= external-declaration translation-unit external-declaration external-declaration ::= function-definition declaration Description A C program consists of one or more translation units, each of which can be compiled separately.
Data Types and Declarations Declarations Declarations A declaration specifies the attributes of an identifier or a set of identifiers.
Data Types and Declarations Declarations const float pi = 3.
Data Types and Declarations Storage-Class Specifiers Storage-Class Specifiers A storage-class specifier is one of several keywords that determines the duration and linkage of an object. Syntax storage-class ::= typedef extern static auto register Description You can use only one storage-class specifier in a declaration. The typedef keyword is listed as a storage-class specifier because it is syntactically similar to one. The keyword extern affects the linkage of a function or object name.
Data Types and Declarations Storage-Class Specifiers Refer to chapter 2 for a description of storage duration and linkage.
Data Types and Declarations Type Specifiers Type Specifiers Type specifiers indicate the format of the storage associated with a given data object or the return type of a function. Syntax type-specifier ::= char short int long unsigned signed float double void struct-or-union-specifier enum-specifier typedef-name Description Most of the type specifiers are single keywords. (Refer to chapter 9 for sizes of types.
Data Types and Declarations Type Specifiers Table 3-1. C Type Specifiers double long double struct-or-union specifier enum-specifier typedef-name If no type specifier is provided in a declaration, the default type is int. Floating-point types in C are float (32 bits), double (64 bits), and long double (128 bits).
Data Types and Declarations Type Qualifiers Type Qualifiers Syntax type-qualifier ::= const volatile Description This section describes the type qualifiers — volatile and const. The volatile type qualifier directs the compiler not to perform certain optimizations on an object because that object can have its value altered in ways beyond the control of the compiler.
Data Types and Declarations Type Qualifiers Table 3-2. Declarations using const and volatile Declaration Meaning int const *volatile vpci; Declares a volatile pointer to a constant int. const *pci; Declares a pointer to a constant int. Since no type specifier was given, it defaults to int. When a type qualifier is used with a variable typed by a typedef name, the qualifier is applied without regard to the contents of the typedef.
Data Types and Declarations Structure and Union Specifiers Structure and Union Specifiers A structure specifier indicates an aggregate type consisting of a sequence of named members. A union specifier defines a type whose members begin at offset zero from the beginning of the union.
Data Types and Declarations Structure and Union Specifiers Unions are like structures except that all members of a union have a zero offset from the beginning of the union. In other words, the members overlap. Unions are a way to store different type of objects in the same memory location. A declarator for a member of a structure or union may occupy a specified number of bits. This is done by following the declarator with a colon and a constant non-negative integral expression.
Data Types and Declarations Structure and Union Tags Structure and Union Tags Structures and unions are declared with the struct or union keyword. You can follow the keywords with a tag that names the structure or union type much the same as an enum tag names the enumerated type. (Refer to the section 'Enumeration' later in this chapter for information on enumerated types.) Then you can use the tag with the struct or union keyword to declare variables of that type without respecifying member declarations.
Data Types and Declarations Structure and Union Tags may contain a pointer to a structure of type S as one of its members. Note that a structure can never have itself as a member because the definition of the structure's content would be recursive. A pointer to a structure is of fixed size, so it may be a member. Structures that contain pointers to themselves are key to most interesting data structures.
Data Types and Declarations Enumeration Enumeration The identifiers in an enumeration list are declared as constants. Syntax enum-specifier ::= enum[ identifier] {enumerator-list} enum [ identifier ] enumerator-list ::= enumerator enumerator-list , enumerator enumerator ::= enumeration-constant enumeration-constant = constant-expression enumeration-constant ::= identifier Description The identifiers defined in the enumerator list are enumeration constants of type int.
Data Types and Declarations Enumeration Examples enum color {RED, GREEN, BLUE}; enum objectkind {triangle, square=5, circle}; 40 /* circle == 6 */ Chapter 3
Data Types and Declarations Declarators Declarators A declarator introduces an identifier and specifies its type, storage class, and scope.
Data Types and Declarations Declarators Declarator operators have the same precedence and associativity as operators appearing in expressions. Function declarators and array declarators bind more tightly than pointer declarators. You can change the binding of declarator operators using parentheses. For example, int *x[10]; is an array of 10 pointers to ints. This is because the array declarator binds more tightly than the pointer declarator.
Data Types and Declarations Declarators • If the array is a formal parameter in a function definition. • If the array declaration contains an initializer. • If the array declaration has external linkage and the definition (in another translation unit) that actually allocates storage provides the dimension.
Data Types and Declarations Declarators Functions can also return structures. If a function returns a structure as a result, the called function copies the resulting structure into storage space allocated in the calling function. The length of time required to do the copy is directly related to the size of the structure. If pointers to structures are returned, the execution time is greatly reduced.
Data Types and Declarations Type Names Type Names A type name is syntactically a declaration of an object or a function of a given type that omits the identifier. Type names are often used in cast expressions and as operands of the sizeof operator.
Data Types and Declarations Type Definitions Using typedef Type Definitions Using typedef The typedef keyword, useful for abbreviating long declarations, allows you to create synonyms for C data types and data type definitions. Syntax typedef-name ::= identifier Description If you use the storage class typedef to declare an identifier, the identifier is a name for the declared type rather than an object of that type. Using typedef does not define any objects or storage.
Data Types and Declarations Type Definitions Using typedef unsigned li x; typedef identifiers occupy the same name space as ordinary identifiers and follow the same scoping rules. Structure definitions which are used in typedef declarations can also have structure tags. These are still necessary to have self-referential structures and mutually referential structures.
Data Types and Declarations Initialization Initialization An initializer is the part of a declaration that provides the initial values for the objects being declared. Syntax initializer ::= assignment-expression {initializer-list} {initializer-list , } initializer-list ::= initializer initializer-list , initializer Examples wchar_t wide_message[ ]=L"x$$z"; You initialize structures as you do any other aggregate: struct{ int i; unsigned u:3; unsigned v:5; float f; char *p; } s[ ] = { {1, 07, 03, 3.
Data Types and Declarations Initialization storage duration are initialized at runtime when entering the block that contains the definition of the object. An initialization of such an object is similar to an assignment statement. You can initialize a static object with a constant expression. You can initialize a static pointer with the address of any previously declared object of the appropriate type plus or minus a constant. You can initialize an auto scalar object with an expression.
Data Types and Declarations Initialization As a special case, you can initialize an array of characters with a character string literal. If the dimension of the array of characters is not provided, the compiler counts the number of characters in the string literal to determine the size of the array. Note that the terminating '\0' is also counted. For example: char message[ ] = "hello"; This example defines an array of characters named message that contains six characters.
Data Types and Declarations Initialization Union initialization is only available in ANSI mode.
Data Types and Declarations Function Definitions Function Definitions A function definition introduces a new function. Syntax function-definition ::= [declaration-specifiers] declarator [declaration-list] compound-statement Description A function definition provides the following information about the function: 1. Type. You can specify the return type of the function. If no type is provided, the default return type is int.
Data Types and Declarations Function Definitions You can declare formal parameters as structures or unions. When the function is called, the calling function's argument is copied to temporary locations within the called function. All functions in C may be recursive. They may be directly recursive so the function calls itself or they may be indirectly recursive so a function calls one or more functions which then call the original function. Indirect recursion can extend through any number of layers.
Data Types and Declarations Function Definitions int p1, p2; { int l1; l1 = p1 + p2; return l1; } /* parameter declarations */ /* function body starts */ /* local variables */ Here is an example of a function definition using prototypes. char *func2 (void) /* new-style definition */ /* takes no parameters */ { /* body */ } int func3 (int p1, char *p2, ...) of unspecified type /* two declared parameters: p1 & p2 */ /* "...
Type Conversions 4 Type Conversions The use of different types of data within C programs creates a need for data type conversions. For example, some circumstances that may require a type conversion are when a program assigns one variable to another, when it passes arguments to functions, or when it tries to evaluate an expression containing operands of different types. C performs data conversions in these situations. • Assignment — Assignment operations cause some implicit type conversions.
Type Conversions Integral Promotions Integral Promotions Wherever an int or an unsigned int can be used in an expression, a narrower integral type can also be used. The narrow type will generally be widened by means of a conversion called an integral promotion. All ANSI C compilers follow what are called value preserving rules for the conversion.
Type Conversions Usual Arithmetic Conversions Usual Arithmetic Conversions In many expressions involving two operands, the operands are converted according to the following rules, known as the usual arithmetic conversions. The common type resulting from the application of these rules is also the type of the result. These rules are applied in the sequence listed below. 1. If either operand is long double, the other operand is converted to long double. 2.
Type Conversions Arithmetic Conversions Arithmetic Conversions In general, the goal of conversions between arithmetic types is to maintain the same magnitude within the limits of the precisions involved. A value converted from a less precise type to a more precise type and then back to the original type results in the same value. Integral Conversions A particular bit pattern, or representation, distinguishes each data object from all others of that type.
Type Conversions Arithmetic Conversions i = -9.99; /* i gets the value -9 */ float x1 = 1e38; /* legal; double is converted to float float x2 = 1e39; /* illegal; value is outside of range /* for float */ long double x3 = 1.
Type Conversions Arithmetic Conversions 54 Chapter 4
Expressions 5 Expressions This chapter describes forming expressions in C, discusses operator precedence, and provides details about operators used in expressions. An expression in C is a collection of operators and operands that indicates how a computation should be performed. Expressions are represented in infix notation. Each operator has a precedence with respect to other operators. Expressions are building blocks in C. You use the C character set to form tokens.
Expressions Operator Precedence Operator Precedence Precedence is the order in which the compiler groups operands with operators. The C compiler evaluates certain operators and their operands before others. If operands are not grouped using parentheses, the compiler groups them according to its own rules. shows the rules of operator precedence in the C language. lists the highest precedence operators first.
Expressions Operator Precedence Table 5-1. C Operator Precedence 1 Operators Grouping = *= /= %= += -= <<= >>= &= ^= |= right to left , left to right Note that the +, -, *, and operators listed in this row are unary operators.
Expressions Lvalue Expressions Lvalue Expressions An lvalue (pronounced "el-value") is an expression that designates an object. A modifiable lvalue is an lvalue that does not have an array or an incomplete type and that does not have a "const"-qualified type. The term "lvalue" originates from the assignment expression E1=E2, where the left operand E1 must be a modifiable lvalue. It can be thought of as representing an object "locator value.
Expressions Primary Expressions Primary Expressions The term primary expression is used in defining various C expressions. Syntax primary-expression := identifier constant string-literal (expression) Description A primary expression is an identifier, a constant, a string literal, or an expression in parentheses that may or may not be an lvalue expression. Primary expressions are the basic components of all expressions. An identifier can be a primary expression provided that you have declared it properly.
Expressions Postfix Operators Postfix Operators Postfix operators are unary operators that attach to the end of postfix expressions. A postfix expression is any expression that may be legally followed by a postfix operator. Syntax postfix-expression := primary-expression postfix-expression postfix-expression postfix-expression postfix-expression postfix-expression postfix-expression [ expression ] ( [argument-expression-list] ) .
Expressions Array Subscripting Array Subscripting A postfix expression followed by the [ ] operator is a subscripted reference to a single element in an array. Syntax postfix-expression [ expression ] Description One of the operands of the subscript operator must be of type pointer to T (T is an object type), the other of integral type. The resulting type is T. The [ ] operator is defined so that E1[E2] is identical to (*((E1)+(E2))) in every respect.
Expressions Function Calls Function Calls Function calls provide a means of invoking a function and passing arguments to it. Syntax postfix-expression ( [argument-expression-list] ) Description The postfix-expression must have the type "pointer to function returning T." The result of the function will be type T. Functions can return any type of object except array and function. Specifically, functions can return structures.
Expressions Function Calls Thus, for safety, it is highly advisable to use prototypes wherever possible. In both cases, arrays of type T are converted to pointers to type T, and functions are converted to pointers to functions. Within a function, the formal parameters are lvalues that can be changed during the function execution. This does not change the arguments as they exist in the calling function. It is possible to pass pointers to objects as arguments.
Expressions Structure and Union Members Structure and Union Members A member of a structure or a union can be referenced using either of two operators: the period or the right arrow. Syntax postfix-expression . identifier postfix-expression -> identifier Description Use the period to reference members of structures and unions directly. Use the arrow operator to reference members of structures and unions pointed to by pointers.
Expressions Postfix Increment and Decrement Operators Postfix Increment and Decrement Operators The postfix increment operator ++ adds one to its operand after using its value. The postfix decrement operator subtracts one from its operand after using its value. Syntax postfix-expression postfix-expression Description You can only apply postfix increment ++ and postfix decrement operators to an operand that is a modifiable lvalue with scalar type.
Expressions Unary Operators Unary Operators You form unary expressions by combining a unary operator with a single operand. All unary operators are of equal precedence and group from right to left.
Expressions Prefix Increment and Decrement Operators Prefix Increment and Decrement Operators The prefix increment or decrement operator increments or decrements its operand before using its value. Syntax unary-expression unary-expression Description The operand for the prefix increment ++ or the prefix decrement operator must be a modifiable lvalue with scalar type. The result is not an lvalue. The operand of the prefix increment operator is incremented by 1.
Expressions Address and Indirection Operators Address and Indirection Operators The address () and indirection (*) operators are used to locate the address of an operand and indirectly access the contents of the address. Syntax cast-expression * cast-expression Description The operand of the unary indirection operator (*) must be a pointer to type T. The resulting type is T. If type T is not a function type, the unary-expression is an lvalue. The contents of pointers are memory addresses.
Expressions Unary Arithmetic Operators Unary Arithmetic Operators A unary arithmetic operator combined with a single operand forms a unary expression used to negate a variable, or determine the ones complement or logical complement of the variable. Syntax + ~ ! cast-expression cast-expression cast-expression cast-expression Description The unary plus operator operates on a single arithmetic operand, as is the case of the unary minus operator.
Expressions The sizeof Operator The sizeof Operator The sizeof operator is used to determine the size (in bytes) of a data object or a type. Syntax sizeof unary-expression sizeof (type-name) Description The result of the sizeof operator is an unsigned int constant expression equal to the size of its operand in bytes. You can use the sizeof operator in two different ways. First, you can apply the sizeof operator to an expression.
Expressions Cast Operators Cast Operators The cast operator is used to convert an expression of one type to another type. Syntax cast-expression := unary-expression (type-name) cast-expression Description An expression preceded by a parenthesized type name causes the expression to be converted to the named type. This operation is called a cast. The cast does not alter the type of the expression, only the type of the value.
Expressions Multiplicative Operators Multiplicative Operators The multiplicative operators perform multiplication (*), division (/), or remainder (%). Syntax multiplicative-expression := cast-expression multiplicative-expression * cast-expression multiplicative-expression / cast-expression multiplicative-expression cast-expression Description Each of the operands in a multiplicative expression must have arithmetic type. Further, the operands for the % operator must have integral type.
Expressions Multiplicative Operators operands, when the result is not zero. Table 5-3.
Expressions Additive Operators Additive Operators The additive operators perform addition (+) and subtraction (-). Syntax additive-expression := multiplicative-expression additive-expression multiplicative-expression additive-expression - multiplicative-expression Description The result of the binary addition operator + is the sum of two operands. Both operands must be arithmetic, or one operand can be a pointer to an object type and the other an integral type.
Expressions Bitwise Shift Operators Bitwise Shift Operators The bitwise shift operators shift the left operand left (\<\<) or right (\>\>) by the number of bit positions specified by the right operand. Syntax shift-expression := additive-expression shift-expression << additive-expression shift-expression >> additive-expression Description Both operands must be of integral type. The integral promotions are performed on both operands. The type of the result is the type of the promoted left operand.
Expressions Relational Operators Relational Operators The relational operators compare two operands to determine if one operand is less than, greater than, less than or equal to, or greater than or equal to the other.
Expressions Equality Operators Equality Operators The equality operators equal-to (==) and not-equal-to (!=) compare two operands. Syntax equality-expression := relational-expression equality-expression relational-expression equality-expression != relational-expression Description The usual arithmetic conversions are performed on the operands if both have arithmetic type.
Expressions Bitwise AND Operator Bitwise AND Operator The bitwise AND operator (&) performs a bitwise AND operation on its operands. This operation is useful for bit manipulation. Syntax AND-expression ::= equality-expression AND-expression & equality-expression Description The result of the binary & operator is the bitwise AND function of the two operands. Both operands must be integral types. The usual arithmetic conversions are performed on the operands.
Expressions Bitwise Exclusive OR Operator Bitwise Exclusive OR Operator The bitwise exclusive OR operator (^) performs the bitwise exclusive OR function on its operands. Syntax exclusive-OR-expression ::= AND-expression exclusive-OR-expression ^ AND-expression Description The result of the binary operator is the bitwise exclusive OR function of the two operands. Both operands must be integral types. The usual arithmetic conversions are performed on the operands.
Expressions Bitwise Inclusive OR Operator Bitwise Inclusive OR Operator The bitwise inclusive OR operator (|) performs the bitwise inclusive OR function on its operands. Syntax inclusive-OR-expression := exclusive-OR-expression inclusive-OR-expression | exclusive-OR-expression Description The result of the binary operator is the bitwise OR function of the two operands. Both operands must be integral types. The usual arithmetic conversions are performed on the operands.
Expressions Logical AND Operator Logical AND Operator The logical AND operator (&&) performs the logical AND function on its operands. Syntax logical-AND-expression := inclusive-OR-expression logical-AND-expression && inclusive-OR-expression Description Each of the operands must have scalar type. The type of the left operand need not be related to the type of the right operand. The result has type int and has a value of 1 if both of its operands compare unequal to 0, and 0 otherwise.
Expressions Logical OR Operator Logical OR Operator The logical OR operator () performs the logical OR function on its operands. Syntax logical-OR-expression := logical-AND-expression logical-OR-expression || logical-AND-expression Description Each of the operands must be of scalar type. The type of the left operand need not be related to the type of the right operand. The result has type int and has a value of 1 if either of its operands compare unequal to 0, and 0 otherwise.
Expressions Conditional Operator Conditional Operator The conditional operator (?:) performs an if-then-else using three expressions. Syntax conditional-expression := logical-OR-expression logical-OR-expression ? expression : conditional-expression Description A conditional expression consists of three expressions. The first and the second expressions are separated with a ? character; the second and third expressions are separated with a : character. The first expression is evaluated.
Expressions Conditional Operator Example This expression returns x if a is 0, or return y if a is not 0. a == 0 ? x : y The following statement prints "I have 1 dog." if num is equal to 1, or "I have 3 dogs.", if num is 3. printf ("I have %d dog%s.
Expressions Assignment Operators Assignment Operators Assignment operators assign the value of the right operand to the object designated by the left operand. Syntax assignment-expression ::= conditional-expression unary-expression assignment-operator assignment-expression assignment-operator := one selected from the set = *= /= %= += -= <<= >>= &= ^= |= Description Each assignment operator must have a modifiable lvalue as its left operand. An assignment operator stores a value into the left operand.
Expressions Assignment Operators another pointer. No cast is necessary to convert a "pointer to void" to any other type of pointer. An assignment is not only an operation, it is also an expression. Each operand must have an arithmetic type consistent with those allowed by the binary operator that is used to make up the assignment operator. You can use the += and -= operators with a left operand that is a pointer type.
Expressions Comma Operator Comma Operator The comma operator is a binary operator whose operands are expressions. The expression operands are evaluated from left to right. Syntax expression ::= assignment-expression expression , assignment-expression Description The comma operator is a "no-operation" operator. Its left operand is evaluated for its side effects only. Its value is discarded. The right operand is then evaluated and the result of the expression is the value of the right operand.
Expressions Constant Expressions Constant Expressions Constant expressions are expressions that can be evaluated during translation rather than run-time. Syntax constant-expression ::= conditional-expression Description A constant expression must evaluate to an arithmetic constant expression, a null pointer constant, an address constant, or an address constant plus or minus an integral constant expression.
Statements 6 Statements This chapter describes the statements in the C programming language. The statements are grouped as follows: • Labeled Statements • Compound Statement or Block • Expressions and Null Statement • Selection Statements • Iteration Statements • Jump Statements Statements are the executable parts of a C function. The computer executes them in the sequence in which they are presented in the program, except where control flow is altered as specified in this chapter.
Statements Labeled Statements Labeled Statements Labeled statements are those preceded by a label. Syntax labeled-statement ::= identifier : statement case constant-expression : statement default: statement Description You can prefix any statement using a label so at some point you can reference it using goto statements. This includes statements already having labels. In other words, any statement can have one or more labels affixed to it.
Statements Compound Statement or Block Compound Statement or Block Compound or block statements allow you to group other statements together in a block of code. Syntax compound-statement ::= {[declaration-list][statement-list]} declaration-list ::= declaration declaration-list declaration statement-list ::= statement statement-list statement Description You can group together a set of declarations and statements and use them as if they were a single statement.
Statements Selection Statements Selection Statements A selection statement alters a program's execution flow by selecting one path from a collection based on a specified controlling expression. The if statement and the switch statement are selection statements.
Statements The if Statement The if Statement The if statement executes a statement depending on the evaluation of an expression. Syntax if (expression ) statement if (expression ) statement else statement Description The if statement is for testing values and making decisions. An if statement can optionally include an else clause. For example: if (j<1) func(j); else { j=x++; func(j); } The first statement is executed only if the evaluated expression is true (i.e., evaluates to a nonzero value).
Statements The if Statement The tests are each executed in order until successful or until the end of the selection statement is reached. In the previous example, if a is equal to d, all three comparisons would be executed. On the other hand, if a is equal to c, only the first two comparisons are executed. Therefore, conditions that are most likely to be true should be tested first in an else-if chain. The switch statement, however, may execute only one comparison (depending on efficiency tradeoffs).
Statements The switch Statement The switch Statement The switch statement executes one or more of a series of cases based on the value of an expression. It offers multiway branching. Syntax switch (expression) statement Description The expression after the word switch is the controlling expression. The controlling expression must have integral type. The statement following the controlling expression is typically a compound statement. The compound statement is called the switch body.
Statements The switch Statement break; case 'l': case 'L': moveleft ( ); break; case 'b': case 'B': moveback ( ); break; case 'a': case 'A': default: moveahead ( ); break; } 88 Chapter 6
Statements Iteration Statements Iteration Statements You use iteration statements to force a program to execute a statement repeatedly. The executed statement is called the loop body. Loops execute until the value of a controlling expression is 0. The controlling expression may be of any scalar type. C has several iteration statements: while, do-while, and for. The main difference between these statements is the point at which each loop tests for the exit condition.
Statements The while Statement The while Statement The while statement evaluates an expression and executes the loop body until the expression evaluates to false. Syntax while (expression) statement Description The controlling expression is evaluated at run time. If the controlling expression has a nonzero value, the loop body is executed. Then control passes back to the evaluation of the controlling expression.
Statements The do Statement The do Statement The do statement executes the loop body one or more times until the expression in the while clause evaluates to 0. Syntax do statement while (expression) Description The loop body is executed. The controlling expression is evaluated. If the value of the expression is nonzero, control passes to the first statement of the loop body. Note that the test for a zero value is performed after execution of the loop body.
Statements The for Statement The for Statement The for statement evaluates three expressions and executes the loop body until the second expression evaluates to false. Syntax for ([expression1] ; [expression2]; [expression3]) statement Description The for statement is a general-purpose looping construct that allows you to specify the initialization, termination, and increment of the loop. The for uses three expressions. Semicolons separate the expressions.
Statements Jump Statements Jump Statements Jump statements cause the unconditional transfer of control to another place in the executing program.
Statements Jump Statements { if ((++i % 5) == 0) printf ("%2d ", i); if (i > 100) { printf ("\n"); return; /* unconditional jump to calling function } */ } 94 Chapter 6
Statements The goto Statement The goto Statement The goto statement transfers control to a labeled statement that is within the scope of the current function. Syntax goto identifier ; Description The goto statement causes an unconditional branch to the named label in the current function. Because you can use goto statements to jump to any statement that can be labeled, the potential for their abuse is great.
Statements The continue Statement The continue Statement The continue statement is used to transfer control during the execution of an iteration statement. Syntax continue; Description The continue statement unconditionally transfers control to the loop-continuation portion of the most tightly enclosing iteration statement. You cannot use the continue statement without an enclosing for, while, or do statement.
Statements The break Statement The break Statement The break statement terminates the enclosing switch or iteration statement. Syntax break; Description A break statement terminates the execution of the most tightly enclosing switch or iteration statement. Control is passed to the statement following the switch or iteration statement. You cannot use a break statement unless it is enclosed in a switch or iteration statement.
Statements The return Statement The return Statement The return statement causes a return from a function. Syntax return [expression]; Description When a return statement is executed, the current function is terminated and control passes back to the calling function. In addition, all memory previously allocated to automatic variables is considered unused and may be allocated for other purposes.
Preprocessing Directives 7 Preprocessing Directives Preprocessing directives function as compiler control lines. They enable you to direct the compiler to perform certain actions on the source file. You can use the preprocessing directives to make a number of textual changes in the source before it is syntactically and semantically analyzed and translated.
Preprocessing Directives characters and the preprocessing directive. The directive is terminated by a new-line character. You can continue directives, as well as normal source lines, over several lines by ending lines that are to be continued with a backslash (\). NOTE In ANSI mode, white space may precede the # character in preprocessing directives. Comments in the source file that are not passed by default through the preprocessor are replaced with a single white-space character.
Preprocessing Directives Source File Inclusion Source File Inclusion You can include the contents of other files within the source file using the #include directive. Syntax include-directive := #include #include "filename" #include identifier Description The #include preprocessor directive enables you to insert the contents of the specified external file into the source file prior to compilation.
Preprocessing Directives Source File Inclusion Examples #include #include "myheader" #ifdef MINE # define filename #else # define filename #endif "file1" "file2" #include filename Preprocessor Search of Include Files in Quotation Marks The preprocessor searches for include files enclosed in double quotation marks, (for example #include myfile), as follows: 1. If the include filename contains an MPE/iX group and account name, then the preprocessor searches the specified group and account.
Preprocessing Directives Source File Inclusion levels of nested include files. Note that this search path is based on the group and account where the source file is located and not where the include file is "included". To illustrate, assuming that a program MAIN.SRCGROUP.SRCACCT contains the following directive: #include "HEADER1.X.Y" and HEADER1.X.Y contains another include directive: #include "HEADER2" The preprocessor looks for HEADER2.SRCGROUP.SRCACCT even though the file that includes it is in X.Y.
Preprocessing Directives Source File Inclusion the SYS account, but never searches the group and account in which the source file is located. When the name is enclosed in double quotation marks, the group and account in which the source file is located is searched. If you use the -I compiler option, the indicated groups and accounts are searched before the H and H.SYS groups and accounts are searched, regardless of which characters surround the name.
Preprocessing Directives Recommendations for Using Include Files Recommendations for Using Include Files If you have include files or source files spread throughout your file system, you may want to become familiar with the following recommendations for arranging include files in a flexible and consistent manner. However, if you keep all source and include files in a single group and account on your system, the recommendations listed below may not be useful to you.
Preprocessing Directives Recommendations for Using Include Files It is important to note that a fully qualified formal designator is required for the file to be successfully equated, as the preprocessor builds a fully qualified file name before attempting an open. The exception to this rule is when the preprocessor opens a file using a -I option that only specifies a group.
Preprocessing Directives Macro Replacement Macro Replacement You can define text substitutions in your source file with C macro definitions. Syntax macro-directive := #define identifier [replacement-list] #define identifier ( [identifier-list] ) [replacement-list] #undef identifier replacement-list := token replacement-list token Description A #define preprocessing directive of the form: #define identifier [replacement-list] defines the identifier as a macro name that represents the replacement list.
Preprocessing Directives Macro Replacement If a formal parameter in the macro definition directive's token string follows a # operator, it is replaced by the corresponding argument from the macro invocation, preceded and followed by a double-quote character (") to create a string literal. This feature may be used to turn macro arguments into strings. This feature is often used with the fact that the compiler concatenates adjacent strings.
Preprocessing Directives Macro Replacement operators that might be used with the MAX macro. Using a macro definition for MAX has some advantages over a function definition. First, it executes faster because the macro generates in-line code, avoiding the overhead of a function call. Second, the MAX macro accepts any argument types. A functional implementation of MAX would be restricted to the types defined for the function.
Preprocessing Directives Predefined Macros Predefined Macros ANSI C provides the , , , , and predefined macros. Table 7-1 describes the complete set of macros that are predefined to produce special information. They may not be undefined. Table 7-1. Predefined Macros Macro Name Description Produces the date of compilation in the form Mmm dd yyyy. Produces the name of the file being compiled. Produces the current source line number.
Preprocessing Directives Conditional Compilation Conditional Compilation Conditional compilation directives allow you to delimit portions of code that are compiled if a condition is true.
Preprocessing Directives Conditional Compilation #ifdef max #ifndef min The #if preprocessing directive has the form: #if constant-expression Use #if to test an expression. The compiler evaluates the expression in the directive. If it is true (a nonzero value), the code following the directive is included. If the expression evaluates to false (a zero value), the compiler ignores the code up to the next #else, #endif, or #elif directive.
Preprocessing Directives Conditional Compilation /* compiled if A evaluates < 20 */ # else # endif #endif /* compiled if A >= 20 and <= 47 */ /* end of if, A < 20 */ /* end of if, A > 47 */ #ifdef (HP9000_S800) # define INT_SIZE 32 #elif defined (HPVECTRA) # define INT_SIZE 16 /* /* && /* /* /* If HP9000_S800 is defined, INT_SIZE is defined to be 32 (bits). defined (SMALL_MODEL) Otherwise, if HPVECTRA and SMALL_MODEL are defined, INT_SIZE is defined to be 16 (bits).
Preprocessing Directives Line Control Line Control You can cause the compiler to increment line numbers during compilation from a number specified in a line control directive. (The resulting line numbers appear in error message references, but do not alter the line numbers of the actual source code.
Preprocessing Directives Pragma Directive Pragma Directive You can provide instructions to the compiler through inclusion of pragmas. Syntax pragma-directive := #pragma replacement-list Description The #pragma preprocessing directive provides implementation-dependent information to the compiler. Any pragma that is not recognized by the compiler is ignored. See chapter 8 for descriptions of pragmas recognized by HP C/iX.
Preprocessing Directives Error Directive Error Directive Syntax #error [pp-tokens] The #error directive causes a diagnostic message, along with any included token arguments, to be produced by the compiler.
Preprocessing Directives Trigraph Sequences Trigraph Sequences The C source code character set is a superset of the ISO 646-1983 Invariant Code Set. To enable programs to be represented in the reduced set, trigraph sequences are defined to represent those characters not in the reduced set. A trigraph is a three character sequence that is replaced by a corresponding single character. Table 7-2 gives the complete list of trigraph sequences and their replacement characters. Table 7-2.
Preprocessing Directives Trigraph Sequences 114 Chapter 7
Compiling and Running HP C/iX Programs 8 Compiling and Running HP C/iX Programs This chapter describes how to compile, link, and run HP C programs on the MPE/iX operating system. The following steps must occur before you can execute an HP C/iX program: 1. Translate the source code into an object file. 2. Link one or more object files into a program file. 3. Load and execute the program file. You can perform each of these steps independently, controlling the details of each step.
Compiling and Running HP C/iX Programs Compiling HP C/iX Programs Compiling HP C/iX Programs You can compile HP C/iX programs using the MPE/iX commands CCXL, CCXLLK or CCXLGO, or by explicitly running the CCOMXL.PUB.SYS program. CCXL Command The CCXL command invokes the HP C/iX compiler and generates an object file. Syntax CCXL [textfile] [,[objectfile] [,[listfile]] [;INFO="options"] Parameters textfile is the source file that the HP C/iX compiler reads. If omitted, the default is $STDIN.
Compiling and Running HP C/iX Programs Compiling HP C/iX Programs CCXLLK Command The CCXLLK command invokes the HP C/iX compiler, generates an object file, and links the object file with the HP C/iX library to produce an executable program file. Syntax CCXLLK [textfile] [,[programfile] [,[listfile]] [;INFO="options"] Parameters textfile is the source file that the HP C/iX compiler reads. If omitted, the default is $STDIN. programfile is the program file to which the linker writes the linked program.
Compiling and Running HP C/iX Programs Compiling HP C/iX Programs Parameters textfile is the source file that the HP C/iX compiler reads. If omitted, the default is $STDIN. listfile is the listing file. If omitted, the default is $STDLIST. options are compiler options you want to take effect; separate options with a blank. See "HP C/iX Compiler Options" later in this chapter for specific options. Description If you omit textfile, the current input device, $STDIN, is used by default.
Compiling and Running HP C/iX Programs Compiling HP C/iX Programs Table 8-1. Default Files and Designators File Type Default Designator List $STDLIST CCLIST The PARM parameter of the RUN command indicates which files have been equated. This directs the compiler to use these files instead of the default files. The RUN command takes a PARM parameter with an integral value in the range 0 to 7.
Compiling and Running HP C/iX Programs HP C/iX Compiler Options HP C/iX Compiler Options You can pass options to the HP C/iX compiler in the INFO parameter of the CCXL, CCXLLK, and CCXLGO commands, or using the INFO parameter of the RUN command, if you invoke the compiler using CCOMXL.PUB.SYS. You must separate options with a blank. Any string of characters not separated with a blank is considered a single option.
Compiling and Running HP C/iX Programs HP C/iX Compiler Options Option Description -P Only runs the preprocessing phase on the source file and stores the result in the file normally used for the object file. For example, preprocessor output from the command CCXL MYSOURCE, CPPLIST;INFO="-P" is sent to the ASCII file CPPLIST. -Uname Removes any initial definition of name in the preprocessing phase.
Compiling and Running HP C/iX Programs HP C/iX Compiler Options Argument Description -Oopt Invokes optimizations selected by opt. If opt is 1, only level 1 optimizations are performed. If opt is 2, all optimizations are performed. The option +02 is the same as -O. -Rnum Only allows the first num 'register' variables to actually have the 'register' class. Use this option when the register allocator issues an "out of general registers" message.
Compiling and Running HP C/iX Programs HP C/iX Compiler Options This example only executes the preprocessing phase on MYTEXT(-P), leaves the output with the comments intact in CPPOUT (-C), and defines debug as 1 (-Ddebug). CCOPTS CI Variable Options may also be passed to the compiler using the Command Interpreter variable CCOPTS. The compiler picks up the value of CCOPTS and places its contents before any arguments in the INFO string.
Compiling and Running HP C/iX Programs Pragmas Pragmas You may include the following pragmas within a source file, but you may not use them within a function. A pragma is valid from the point that it is included to the end of the source file or until another pragma changes its status. [#pragma OPTIMIZE {ONOFF }] Turns all optimizations ON or OFF, depending on which option you use.
Compiling and Running HP C/iX Programs Pragmas [#pragma LIST {ONOFF }] Turns listing functionality ON or OFF. The default is ON. [#pragma AUTOPAGE {ONOFF }] When ON, causes a page break in the listing after each function definition. The default is OFF. #pragma LOCALITY "string" Specifies a name to be associated with the code that is written to a Relocatable Object Module.
Compiling and Running HP C/iX Programs Linking the C Library Linking the C Library This section describes the procedure necessary to link C library functions into your program using the MPE/iX LINK command. For many applications, linking the LIBCINIT.LIB.SYS file in the RL list, as done by the CCXLLK and CCXLGO commands, is sufficient. Applications that use mathematical or random number functions, or programs compiled using ANSI mode, will nee to link with additional libraries.
Compiling and Running HP C/iX Programs Linking the C Library The rand and srand functions are conceptually part of the standard library but reside in a different library file, LIBCRAND.LIB.SYS. To use these functions, add the LIBCRAND.LIB.SYS file to the RL list when linking your program. These functions are not available in XL form. This special treatment for the rand and srand functions is due to a name conflict between the HP C/iX library function rand and the MPE/iX compiler library function rand.
Compiling and Running HP C/iX Programs Running HP C/iX Programs Running HP C/iX Programs You can run HP C/iX programs using the RUN command or by entering the program name (an implied run). You can pass parameters to the main program and redirect the standard input (stdin), standard output (stdout), and error output (stderr) to specific files by using the INFO string.
Compiling and Running HP C/iX Programs Running HP C/iX Programs RUN MYPROG; INFO="STR1 'STR2 WITH BLANKS' STR3" yields: argv[0] argv[1] argv[2] argv[3] argv[4] argc info = = = = = = = MYPROG.MYGROUP.MYACCT "STR1" "STR2 WITH BLANKS" "STR3" NULL 4 "STR1 'STR2 WITH BLANKS' STR3" To include a single quote in a single quoted argument, the following command: RUN MYPROG; INFO="STR1 'STR2 WITH QUOTE HID' 'DEN' STR3" yields: argv[0] argv[1] argv[2] argv[3] argv[4] argc info = = = = = = = MYPROG.MYGROUP.
Compiling and Running HP C/iX Programs Running HP C/iX Programs output and the standard output to the file OUTFILE. In this example, argc is set to 3. The Fileset Wildcard Feature If the fileset wildcard feature is selected when the program is linked, the INFO string handler for a compiled HP C/iX program expands valid fileset wildcards into fully qualified permanent file names and passes them into the main program through the argv vectors. To use the wildcard feature, add the relocatable library LIBCWC.
Compiling and Running HP C/iX Programs Running HP C/iX Programs argv[0] argv[1] argv[2] argv[3] argv[4] argv[5] argv[6] argv[7] argv[8] argc info = = = = = = = = = = = "MYPROG.MYGROUP.MYACCT" "FILE1.MYGROUP.MYACCT" "FILEX.MYGROUP.MYACCT" "MYFILE.MYGROUP.MYACCT" "MYPROG.MYGROUP.MYACCT" "FILE1.MYGROUP.MYACCT" "FILE1.MYGROUP.MYACCT" "FILEX.MYGROUP.
Compiling and Running HP C/iX Programs Running HP C/iX Programs . . exit(7); } or main() { . . return(7); } Either of the above examples sets CJCW to the value of 7 on program termination. If a C program calls the C library routine abort, the system job control word JCW is set to FATAL and a diagnostic message is printed to $STDLIST. CJCW is set to a nonzero value. Arithmetic Traps C/iX programs execute with all arithmetic traps disabled.
Compiling and Running HP C/iX Programs Special Preprocessor Considerations Special Preprocessor Considerations The HP C/iX compiler first executes a preprocessing phase during which all preprocessor directives (lines beginning with #) are interpreted and acted upon. See chapter 7 for detailed information about preprocessing. This section describes features unique to the preprocessing phase on MPE/iX systems.
HP C/iX Implementation Topics 9 HP C/iX Implementation Topics This chapter describes topics that are specific to programming in C on MPE/iX.
HP C/iX Implementation Topics Data Types Data Types Data types are implemented in HP C/iX as follows: • The char type is signed. • All types can have the register storage class, although it is only honored for scalar types. Ten register declarations per function are honored. More are honored when the +R option is used. • The signed integer types are represented internally using twos complement form. • Structures (and unions) start and end on the alignment boundary of their most restrictive member.
HP C/iX Implementation Topics Data Types Comments In the following comments, the low bounds of float, double, and long double data types are given in their normalized and denormalized forms. Normalized and denormalized refer to the way data is stored. Normalized numbers are represented with a greater degree of accuracy than denormalized numbers. Denormalized numbers are very small numbers represented with fewer significant bits than normalized numbers. a. Least normalized: 1.
HP C/iX Implementation Topics Bit-Fields Bit-Fields • Bit-fields in structures are packed from left to right (high-order to low-order). • The high order bit position of a "plain" integer bit-field is treated as a sign bit. • Bit-fields of types char, short, long, and enum are allowed. • The maximum size of a bit-field is 32 bits. • If a bit-field is too large to fit in the current word, it is moved to the next word.
HP C/iX Implementation Topics IEEE Floating-Point Format IEEE Floating-Point Format The internal representation of floating-point numbers conforms to the IEEE floating-point standard, ANSI/IEEE 754-1985, as shown in Figure 9-1. Figure 9-1. Internal Representation of Floating-Point Numbers The s field contains the sign of the number. The exp field contains the biased exponent (exp = E + bias, where E is the real exponent) of the number.
HP C/iX Implementation Topics Lexical Elements not enabled, and the result of such an operation is that defined by the standard. This means, for example, that dividing a positive finite number by zero will yield positive infinity, and no trap will occur. Dividing zero by zero or infinity by infinity will yield a NaN, again with no trap.
HP C/iX Implementation Topics Type Mismatches in External Names Type Mismatches in External Names It is illegal to declare two externally visible identifiers of different types with the same name in separately compiled translation units. The linker might not diagnose such a mismatch. Data Alignment Pragma This section discusses the HP_ALIGN data alignment pragma and the differences between the data alignment architectures of the MPE/iX and MPE/V systems.
HP C/iX Implementation Topics Data Alignment Pragma Figure 9-2. Code Fragment for Comparing Storage and Alignment struct x { char y[3]; short z; char w[5]; }; struct q { char n; struct x v[2]; double u; char t; int s:6; char m; } a = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19, 20.
HP C/iX Implementation Topics Data Alignment Pragma Native Data Alignment on HP C/iX Figure 9-3 shows how the data in Figure 9-2. on page 154 is stored in memory when using HP C/iX. The values are shown above the variable names. Memory locations containing shading are padding bytes. Figure 9-3. Storage with HP C/iX The structure a is aligned on an 8-byte boundary because the most restrictive data type within the structure is the double u.
HP C/iX Implementation Topics Data Alignment Pragma Table 9-3. Padding on HP 9000 Series 700/800 and HP 3000 Series 900 Padding Location Reason for Padding a+5 Aligns the short z on a 2-byte boundary. a+13 Fills out the struct x to a 2-byte boundary. a+17 Aligns the short z on a 2-byte boundary. a+25 Fills out the structure to a 2-byte boundary. a+26 through a+31 Aligns the double u on an 8-byte boundary. The bit-field s begins immediately after the previous item at a+41.
HP C/iX Implementation Topics Data Alignment Pragma Table on page 157 shows the padding for the example code fragment when using HP_ALIGN MPE_16: Table 9-4. Padding Using the HP_ALIGN MPE_16 Pragma Padding Location Reason For Padding a+1 Within structures, align structure x on a 2-byte boundary. a+5 Aligns the short z on a 2-byte boundary. a+13 Structures within structures are aligned on a 2-byte boundary. a+17 Aligns the short z on a 2-byte boundary.
HP C/iX Implementation Topics Pointers to Half-Word Aligned Data Items Pointers to Half-Word Aligned Data Items Pointers in HP C for the HP 3000 Series 900 by default point to objects aligned on 32-bit word addresses. By default, the machine instructions for pointers generated by the compiler depend on the data being word aligned. A run-time memory fault occurs if a pointer to a word-aligned data item accesses a half-word (16-bit) aligned data item.
HP C/iX Implementation Topics Long and Short Pointers Long and Short Pointers HP C defines two classes of data pointers: short and long pointers. A short pointer is a 32-bit pointer that contains the offset of an object local to its process. A long pointer is a 64-bit pointer that may point to an object outside its current process space. The high-order 32 bits of a long pointer contain a space ID number, and the low-order 32 bits represent an offset within the space defined by that space ID.
HP C/iX Implementation Topics Long and Short Pointers contents of that member. To produce a long pointer that points to the same object as a short pointer, you can use an assignment statement. For example, after the assignment statement in the following C code, long_ptr and short_ptr both point to the same object. int ^long_ptr; /* long_ptr is a long pointer to an integer */ int *short_ptr; /* short_ptr is a short pointer to an integer */ . . .
HP C/iX Implementation Topics Expressions Expressions The value of an expression that overflows or underflows is undefined, except when the operands are unsigned. Maximum Number of Dimensions of an Array Arrays can have up to 252 dimensions. Scope of extern Declarations Identifiers for objects and functions declared within a block and with the storage class extern have the same linkage as any visible declaration with file scope.
HP C/iX Implementation Topics Preprocessor • All expressions of integral types are allowed in switch statements. Preprocessor • The maximum nesting depth of #include files is 35. • HP C/iX supports the #line digit-sequence "filename" directive. This directive is used to set the line number and file name for compile time diagnostics. • See chapter 7 "Preprocessing Directives.
HP C/iX Implementation Topics The varargs Macros The varargs Macros The varargs macros allow accessing arguments of functions where the number and types of the arguments can vary from call to call. NOTE The header has been superseded by the standard header , which provides all the functionality of the varargs macros. See the HP C/iX Library Reference Manual for more details on . The
HP C/iX Implementation Topics The varargs Macros va_start(ap); /* Get the first argument, and arg list flag */ a1 = va_arg (ap, int); a2 = va_arg (ap, enum arglisttype); printf ("arg count = %d\n", a1); if (a2 == VAR_LIST_PRESENT) { /* pick up all the arguments */ do { /* get the type of the argument */ ptype = va_arg (ap, enum argtype); /* retrieve the argument based on the type */ switch (ptype) { case CHAR: c = va_arg (ap, char); printf ("char = %c\n", c); break; case DOUB: d = va_arg (ap, double); print
HP C/iX Implementation Topics Location of Files Location of Files The following table lists the location of files used in compiling, linking, and running HP C/iX programs. Table 9-5. Location of Files File or Library Location CCXL CCXL.PUB.SYS CCXLLK CCXLLK.PUB.SYS CCXLGO CCXLGO.PUB.SYS CCSTDRL CCSTDRL.LIB.SYS Compiler CCOMXL.PUB.SYS Preprocessor (non-ANSI) CPP.PUB.SYS Preprocessor (ANSI) CPPANSI.PUB.SYS Error catalog CCMSGCAT.PUB.SYS Linker LINKEDIT.PUB.SYS C Library (RL) LIBC.PUB.
Using Intrinsics 10 Using Intrinsics This chapter describes the use of intrinsic functions in HP C/iX programs. System routines on the MPE/iX operating system are generally referred to as intrinsics because they are an integral or "intrinsic" part of the operating system. The essential characteristic of an intrinsic is that a description of its interface is stored, in a compiled form, in a specially formatted file known as an intrinsic file. MPE/iX intrinsics are described in the file SYSINTR.PUB.SYS.
Using Intrinsics Intrinsic Pragma Intrinsic Pragma You use the intrinsic pragma to declare an external function as an intrinsic. It has the following format: #pragma intrinsic intrinsic-name1 [user-name] [,intrinsic-name2 [user-name] ]... Where: intrinsic-name is the name of the intrinsic you want to call. user-name is any valid C identifier. If specified, you must use this name to invoke the intrinsic from the source program.
Using Intrinsics Intrinsic Pragma • Inserts "hidden" arguments required to correctly call Pascal routines that have ANYVAR parameters (size is hidden) or that are EXTENSIBLE (parameter count is hidden). If you declare a system intrinsic using an extern declaration rather than an intrinsic program, and if you do not provide a function prototype, none of the above checks, conversions, or insertions are done.
Using Intrinsics Intrinsic_file Pragma Intrinsic_file Pragma The intrinsic_file pragma specifies the name of the file in which the compiler can locate information about intrinsic functions. It has the following format: #pragma intrinsic_file "filename" where filename is the fully qualified filename of the file you want the compiler to use to look up information about intrinsics declared using the intrinsic pragma.
Using Intrinsics Condition Codes Condition Codes Condition codes are temporary values that provide basic information about the execution of intrinsics. Many of the MPE/iX intrinsics alter the condition code upon their completion. You can review condition code values to determine the success of an intrinsic call. To recover the condition code, call the HP C/iX library routine, ccode, immediately upon returning from an intrinsic. This ensures that no other instruction alters the condition code.
Using Intrinsics Calling Trap Intrinsics Calling Trap Intrinsics The MPE/iX trap intrinsics often require a plabel parameter that is either by value or by reference. The HP C/iX implementation of plabel is simply the "pointer to function" type. Whenever a function pointer is used, the compiler is actually generating a plabel.
The Listing Facility 11 The Listing Facility The HP C/XL compiler generates a listing by default. This listing appears on the $STDLIST file, or it can be redirected to a file as explained in chapter 8.
The Listing Facility Listing Format Listing Format The listing consists of the following information: • A banner on the top of each page. • A line number for each source line. • The nesting level for each statement or declaration. There are two styles of listing available: non-ANSI mode and ANSI mode. Non-ANSI Mode In non-ANSI mode, the text of the listing is the output of the preprocessor after macro substitution with #include files inserted.
The Listing Facility Listing Pragmas Listing Pragmas The listing facility provides a number of pragmas to control various aspects of the listing format. The available pragmas are described below. #pragma LINES linenum Sets the number of lines per page to linenum. Default is 63. Minimum number is 20 lines. #pragma WIDTH pagewidth Sets the width of the page to pagewidth. Default is 80 columns. Minimum number is 50 columns.
The Listing Facility Listing Options Listing Options Two compiler options are provided to write additional information to the listing. The -Wc,-m (abbreviated +m) option is used to generate identifier maps. The -Wc,-o (abbreviated +o) option is used to generate code offsets. Identifier Maps When the +m option is specified, the compiler produces a series of identifier maps, grouped by function. The map shows the declared identifiers, storage class, type, and address or constant value.
The Listing Facility Listing Options struct SS second_pupil; this_color = red; pupil_rec.sex = 'm'; datum.flag = 1; second_pupil.gpa = 3.
The Listing Facility Listing Options Example #include main(void) { int j; void func1 (int); void func2 (int); for (j=0; ) { func1 (j); func2 (j); } } void func1 (int i) { while (i ) { if (!(i % 5)) printf ("%d is divisible by 5\n", i); ; } } void func2 (int j) { int k, m; k = j % 10 ? 1 : 0; if (k) { m = 23; k = m * m; } } C O D E O F F S E T S main "myfile.
Run-Time Diagnostic Messages A Run-Time Diagnostic Messages This appendix lists the run-time error messages generated by HP C/XL programs. The error messages are listed in numerical order. Possible causes for each error are provided along with actions you may take to correct the error. An example of an HP C run-time error is shown below: **** MISSING NAME FOR REDIRECT (CERR 4) where: MISSING NAME FOR REDIRECT is the message text. CERR indicates the subsystem name.
Run-Time Diagnostic Messages Error Messages Error Messages 1 AMBIGUOUS INPUT REDIRECT More than one input redirection character ( < ) appears in the INFO string. For example, RUN prog; INFO="< infile1 < infile2" Remove one of the input redirection specifiers. 2 AMBIGUOUS OUTPUT REDIRECT More than one output redirection character ( > ) appears in the INFO string. For example, RUN prog; INFO="> outfile1 > outfile2" Remove one of the output redirection specifiers.
Run-Time Diagnostic Messages Error Messages The file specified for output redirection in the INFO string can not be opened. For example, RUN prog; INFO="> badfile" where badfile can not be opened for writing. Check to see if the file specified for redirection is accessible for writing by the user invoking the program. 9 NO FILES FOUND IN FILE-SET A file-set wildcard specified in the INFO string did not match any files. For example, RUN prog; INFO="@.nofiles" where nofiles is a group containing no files.
Syntax Summary B Syntax Summary This appendix presents a summary of the C language syntax as described in this manual.
Syntax Summary Lexical Grammar Lexical Grammar Tokens token ::= keyword identifier constant string-literal operator punctuator preprocessing-token ::= header-name identifier pp-number character-constant string-literal operator punctuator each non-white-space character cannot be one of the above Keywords keyword ::= any word from the set: auto extern sizeof break float static case for struct char goto switch const if typedef continue int union default long unsigned do register void double return volatile e
Syntax Summary Lexical Grammar 0 1 2 3 4 5 6 7 8 9 dollar-sign ::= the $ character Constants constant ::= floating-constant integer-constant enumeration-constant character-constant floating-constant ::= fractional-constant [exponent-part] [floating-suffix] digit-sequence exponent-part [floating-suffix] fractional-constant ::= [digit-sequence] . digit-sequence digit-sequence .
Syntax Summary Lexical Grammar nonzero-digit ::= any character from the set: 1 2 3 4 5 6 7 8 9 octal-digit ::= any character from the set 0 1 2 3 4 5 6 7 hexadecimal-digit ::= any character from the set 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F integer-suffix := unsigned-suffix [long-suffix] long-suffix [unsigned-suffix] unsigned-suffix ::= u U long-suffix ::= l L enumeration-constant ::= identifier character-constant ::= 'c-char-sequence' L'c-char-sequence' c-char-sequence ::= c-char c-char-sequence c-c
Syntax Summary Lexical Grammar String Literals string-literal ::= "[s-char-sequence]" L"[s-char-sequence]" s-char-sequence ::= s-char s-char-sequence s-char s-char ::= any character in the source character set except the double-quote (") , backslash (\), or new-line character escape-sequence Operators operator [ ++ / << ? = , ::= One selected from: ] ( ) .
Syntax Summary Lexical Grammar Preprocessing Numbers pp-number ::= digit . digit pp-number pp-number pp-number pp-number pp-number 202 digit nondigit e sign E sign .
Syntax Summary Phrase Structure Grammar Phrase Structure Grammar Expressions primary-expression ::= identifier constant string-literal ( expression ) postfix-expression ::= primary-expression postfix-expression [ expression ] postfix-expression ( [argument-expression-list] ) postfix-expression .
Syntax Summary Phrase Structure Grammar shift-expression ::= additive-expression shift-expression << additive-expression shift-expression >> additive-expression relational-expression ::= shift-expression relational-expression relational-expression relational-expression relational-expression < shift-expression > shift-expression <= shift-expression >= shift-expression equality-expression ::= relational-expression equality-expression == relational-expression equality-expression != relational-expression AND
Syntax Summary Phrase Structure Grammar constant-expression ::= conditional-expression Declarations declaration ::= declaration-specifiers [init-declarator-list] ; declaration-specifiers ::= storage-class [declaration-specifiers] type-specifier [declaration-specifiers] type-qualifier [declaration-specifiers init-declarator-list ::= init-declarator init-declarator-list , init-declarator init-declarator ::= declarator declarator = initializer storage-class-specifier ::= typedef extern static auto register
Syntax Summary Phrase Structure Grammar struct-declaration struct-declaration-list struct-declaration struct-declaration ::= specifier-qualifier-list struct-declarator-list; specifier-qualifier-list ::= type-specifier [specifier-qualifier-list] type-qualifier [specifier-qualifier-list] struct-declarator-list ::= struct-declarator struct-declarator-list , struct-declarator struct-declarator ::= declarator [declarator] : constant-expression enum-specifier ::= enum [identifier] {enumerator-list} enum [identif
Syntax Summary Phrase Structure Grammar parameter-type-list ::= parameter-list parameter-list , ...
Syntax Summary Phrase Structure Grammar default: statement compound-statement ::= { [declaration-list] [statement-list] } declaration-list ::= declaration declaration-list declaration statement-list ::= statement statement-list statement expression-statement ::= [expression]; selection-statement ::= if (expression) statement if (expression) statement else statement switch ( expression ) statement iteration-statement ::= while ( expression ) statement do statement while ( expression ) for ([expression]; [ex
Syntax Summary Preprocessing Directives Preprocessing Directives preprocessing-file ::= [group] group ::= group-part group group-part group-part ::= [pp-tokens] new-line if-section control-line if-section ::= if-group [elif-groups] [else-group] endif-line if-group ::= # if constant-expression new-line [group] # ifdef identifier new-line [group] # ifndef identifier new-line [group] elif-groups ::= elif-group elif-groups elif-group elif-group ::= # elif constant-expression new-line [group] else-group ::= # e
Syntax Summary Preprocessing Directives new-line ::= the new-line character 210 Appendix B