HP 3000 Manuals

Silent Changes for ANSI C [ HP C Programmer's Guide ] MPE/iX 5.0 Documentation


HP C Programmer's Guide

Silent Changes for ANSI C 

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 or HP C/iX 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:  (1)  

       _________________________________________________________________ 

       FOOTNOTE  (1) Rationale for Proposed American National Standard
                 for Information Systems - Programming Language C (311
                 First Street, N.W., Suite 500, Washington, DC
                 20001-2178; X3 Secretariat:  Computer and Business
                 Equipment Manufacturers Association), pages 34-35

       _________________________________________________________________ 

          *   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 700/800, 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.  */



MPE/iX 5.0 Documentation