HPlogo HP C/HP-UX Programmer's Guide: HP 9000 Computers > Chapter 5 Programming for Portability

Silent Changes for ANSI C

» 

Technical documentation

Complete book in PDF

 » Table of Contents

Non-ANSI mode HP C is different from ANSI mode HP C in ways that generally go unnoticed. On HP-UX, many of these silent differences can be found by running the lint(1) program. The following list provides some of these silent changes:

  • Trigraphs are new in ANSI C. A trigraph is a three character sequence that is replaced by a corresponding single character. For example, ??= is replaced by #. For more information on trigraphs, refer to "Preprocessing Directives" in the HP C/HP-UX Reference Manual.

  • Promotion rules for unsigned char and unsigned short have changed. Non-ANSI mode rules specify when an unsigned char or unsigned short is used with an integer the result is unsigned. ANSI mode rules specify the result is signed. The following program example illustrates a case where these rules differ:

    main(){
    unsigned short us = 1;
    int i = -2;
    printf("%s\n",(i+us)>0 ? "non-ANSI mode" : "ANSI mode");
    }

    Note that differences in promotion rules can occur under the following conditions:

    • An expression involving an unsigned char or unsigned short produces an integer-wide result in which the sign bit is set: that is, either a unary operation on such a type, or a binary operation in which the other operand is int or a "narrower" type.

    • The result of the preceding expression is used in a context in which its condition of being signed is significant: it is the left operand of the right-shift operator or either operand of /,%,<,<=,>, or >=.

  • Floating-point expressions with float operands may be computed as float precision in ANSI mode. In non-ANSI mode they will always be computed in double precision.

  • Initialization rules are different in some cases when braces are omitted in an initialization.

  • Unsuffixed integer constants may have different types. In non-ANSI mode, unsuffixed constants have type int. In the ANSI mode, unsuffixed constants less than or equal to 2147483647 have type int. Constants larger than 2147483647 have type unsigned. For example:

    -2147483648

    has type unsigned in the ANSI mode and int in non-ANSI mode. The above constant is unsigned in the ANSI mode because 2147483648 is unsigned, and the - is a unary operator.

  • Empty tag declarations in a block scope create a new struct instance in ANSI mode. The term block scope refers to identifiers declared inside a block or list of parameter declarations in a function definition that have meaning from their point of declaration to the end of the block. In the ANSI mode, it is possible to create recursive structures within an inner block. For example:

    struct x { int i; };
    { /* inner scope */
    struct x;
    struct y { struct x *xptr; };
    struct x { struct y *yptr; };
    }

    In ANSI mode, the inner struct x declaration creates a new version of the structure type which may then be referred to by struct y. In non-ANSI mode, the struct x; declaration refers to the outer structure.

  • On Series workstations and servers, variable shifts (<< or >>) where the right operand has a value greater than 31 or less than 0 will no longer always have a result of 0. For example,

    unsigned int i,j = 0xffffffff, k = 32;
    i = j >> k; /* i gets the value 0 in compatibility mode, */
    /* 0xffffffff(-1) in ANSI mode. */
© Hewlett-Packard Development Company, L.P.