Jump to content United States-English
HP.com Home Products and Services Support and Drivers Solutions How to Buy
» Contact HP
More options
HP.com home
HP Integrity Servers: HP aC++/HP ANSI C Release Notes > Chapter 2 What’s New in This Version

New Features in Version A.06.20

» 

Technical documentation

Complete book in PDF
» Feedback
Content starts here

 » Table of Contents

 » Index

Version A.06.20 of the HP aC++ compiler supports the following new features:

  • Decimal floating-point arithmetic (HP-UX 11.31 only) (New)

  • +annotate=structs (New)

  • +check=lock (New)

  • +check=thread (New)

  • +O[no]autopar option now supported in C++ mode and implies -mt (New)

  • +O[no]dynopt (New)

  • +inline_level num (Enhanced)

  • -dumpversion (New)

  • #include_next (New)

  • #pragma diag_push (New)

  • #pragma diag_pop (New)

  • +Oinlinebudget is deprecated

  • In next release, default C compilation mode will change from C89 to C99

  • In next release, default C++ compilation mode changes to full -AA

Decimal floating-point arithmetic (HP-UX 11.31 only) (New)

On HP-UX 11.31 systems, support is now included for decimal floating-point arithmetic for C. This support follows the current draft revision of the IEEE 754 floating-point standard and ISO/IEC Technical Report 24732, Extensions for the programming language C to support decimal floating-point arithmetic. With decimal FP (unlike the usual binary FP), typical numerical strings can be represented exactly in the types, avoiding subtle input errors and confusion from inexact output. Therefore, decimal FP is WYSIWYG.

Decimal FP is designed particularly for financial applications, including banking, billing, tax calculation, currency exchange, and accounting.

A decimal FP representation is best thought of as a triple (s, c, q) composed of a sign (1 or −1), an integral coefficient, and a quantum exponent, representing s * c *10q. Therefore, 123. = (1, 123, 0) and 123.00 = (1, 12300, −2) are different representations, although they have the same numerical value and compare equal. Arithmetic operations are defined to preserve the position of the decimal point, much as hand-computation would. For example, 123.00 + 45.6 = 168.60 and 123.00 * 0.01 = 1.2300. These special quantum semantics facilitate exact fix-point calculation. For typical floating-point calculations, the quantum semantics can be ignored.

Decimal FP support includes the following:

  • Three built-in decimal FP types:

    _Decimal32  _Decimal64  _Decimal128
    with 7, 16, and 34 decimal digits of precision, respectively.

  • The usual built-in arithmetic operators for decimal FP operands: +, , *, /, assignments, comparisons, and conversions with integer and binary FP types, all with correctly-rounded IEEE arithmetic. An operation may combine a decimal FP operand with an operand of a different decimal FP type or with an integer type. However, mixing operands of decimal and binary FP types is not allowed.

  • 60 math functions for each decimal FP type. Function suffixes are d32 for _Decimal32, d64 for _Decimal64, and d128 for _Decimal128. Included are:

    • Decimal FP versions of the C99 math functions.

    • New functions to manage quantum exponents (for fixed-point calculation).

    • Routines to encode and decode data for either of the two standard encodings for decimal FP data. Details of the encodings are in the draft revision of IEEE 754, which refers to them as the "binary encoding", which the HP C/aC++ compiler uses, and the "decimal encoding". Both encodings provide exactly the same data, analogous to big endian and little endian encodings.

  • Decimal FP I/O and string conversion. The decimal FP length modifiers for printf()() and scanf()() floating-point conversion specifiers (a, A, e, E, f, F, g, G) are H for _Decimal32, D for _Decimal64, and DD for _Decimal128. The decimal a, A specifiers for printf()(), given no precision or sufficient precision, produce an exact quantum-preserving representation of the decimal FP value being converted.

  • WDB debugger support for printing values of decimal FP types.

  • Suffixes to designate decimal floating constants: df or DF for _Decimal32, dd or DD for _Decimal64, and dl or DL for _Decimal128. Note that an unsuffixed floating constant still has type double, regardless of the context. Explicit suffixing with a d or D to specify type double is also allowed.

  • Decimal FP versions of macros in <float.h>, <math.h>, and <fenv.h>.

  • Five rounding modes for decimal FP: to nearest with ties to even, to nearest with ties away from zero, upward, downward, and toward zero.

  • Compiler option +decfp, which enables full decimal FP functionality according to the ISO/IEC C draft Technical Report: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1312.pdf

  • Compiler option -fpevaldec=precision, which specifies the minimum precision to use for decimal floating-point expression evaluation. The possible values for precision are _Decimal32, _Decimal64, and _Decimal128. This option does not affect the precision of parameters, return types, or assignments. The default is -fpevaldec=_Decimal32.

  • Type-generic functions in <tgmath.h> that take on the type of decimal FP (or binary FP) arguments.

  • Our Decimal FP support incorporates code from the Intel Decimal Floating-Point Math Library.

To use decimal FP:

  • Install the following on an HP-UX 11i V3 (11.31) Integrity system:

  • To use any decimal FP functionality (even built-in operators), add the +decfp option to the compile and link lines.

  • To use the decimal FP functionality in <math.h>, <float.h>, <fenv.h>, or <tgmath.h>, define __STDC_WANT_DEC_FP__ before including the header.

  • To use strtod32(), strtod64(), or strtod128(), include <strtodec.h>. (These interfaces are not declared in <stdlib.h>, as specified in the ISO/IEC C draft Technical Report.)

  • Also see the “HP-UX floating-point guide for HP Integrity servers” at http://www.hp.com/go/fp.

Decimal Floating-Point Example

/***********************************************************************
 *
 * This program is intended to illustrate how C decimal FP might be 
 * used in a commercial billing program.
 *
 * The program reads input data from a file, interprets each datum
 * as a number of service minutes, converts to hours (rounding up to
 * the nearest tenth of an hour), and multiplies by a billing rate 
 * (rounding to the nearest cent with halfway cases rounding away 
 * from zero). For each inputl, the program writes the billing amount
 * as an ASCII character string to a file. Along the way, it 
 * accumulates  sums of service minutes, hours billed, and amounts
 *  billed, and at the end writes the total sums to stdout. 
 *
 * Program constants determine the input and output filenames and
 * whether the input is ASCII, BID ("binary" encoding for decimal FP),
 * or DPD ("decimal" encoding for decimal FP). The HP-UX 
 * implementation uses BID encoding for its decimal FP types.
 * 
 **********************************************************************/

const char * ifilename = "biller.in";              // input file
const char * ofilename = "biller.out";           // output file
const enum { ascii, bid, dpd } encoding = ascii; // input encoding

const _Decimal64 rate = 149.95DD;           // hourly billing rate 

#define __STDC_WANT_DEC_FP__
 
#include <stdio.h>
#include <std.lib.h>
#include <math.h>
#include <fenv.h>
#include <strtodec.h>
#include <assert.h>

#pragma STDC FENV_ACCESS ON

int main() {
    unsigned int n;                        // number of inputs 
    _Decimal64 m;                        // number of minutes 
    _Decimal64 h;                         // number of hours 
    _Decimal64 b;                         // amount billed 
    _Decimal64 sumM, sumH, sumB;    // sums
    const _Decimal64 onert = 0.0DD;     // for rounding to tenths 
    const _Decimal64 twort = 0.00DD;    // for rounding to hundredths
    FILE *inp=NULL;                       // input stream
    FILE *outp=NULL;                     // output stream
    int r, s;                             // fread, scanf returns
    _Binaryencoding64 be;      // for binary-encoded (bid) input
    _Decimalencoding64 de;    // for decimal-encoded (dpd) input
 
    // open input file
    if (encoding == ascii) 
        inp = fopen(ifilename, "r");
    else 
        inp = fopen(ifilename, "rb");
    if (inp == NULL) {
        fprintf(stderr, "FAILURE: could not open %s\n", ifilename);
        exit(EXIT_FAILURE);
    }
 
    // open output file
    outp = fopen(ofilename, "w");
    if (outp == NULL) {
        fprintf(stderr, "FAILURE: could not open %s\n", ofilename);
        exit(EXIT_FAILURE);
    }

// initialize sums
    sumM = 0.DD;
    sumH = 0.0DD;
    sumB = 0.00DD;
 
    // main loop
    for (n=0; ; n++) {
        // read a number
        if (encoding == ascii) {
            s = fscanf(inp, "%De", &m);  
            if (s == 0) { 
                fprintf(stderr, "FAILURE: on input from %s\n", ifilename);
                fclose(inp);
                fclose(outp);
                exit(EXIT_FAILURE);
            }
            if (s == EOF) break;
        }
        else if (encoding == bid) {
               r = (int) fread(&be, sizeof(_Binaryencoding64), 1, inp); 
            if (r != 1) break; 
            m = _decodebinary64(be); // decode bid 
        }
              else /* encoding == dpd */ {
                 r = (int) fread(&de, sizeof(_Decimalencoding64), 1, inp); 
            if (r != 1) break; 
            m = _decodedecimal64(de); // decode dpd
        }

 // compute hours billed
        fe_dec_setround(FE_DEC_UPWARD);
        h = m / 60;
        h = quantized64(h, onert); // round to tenths 
 	
        // compute billing amount
        fe_dec_setround(FE_DEC_TONEARESTFROMZERO);
        b = rate * h;
        b = quantized64(b, twort); // round to hundredths
 
        // restore decimal rounding mode to default
        fe_dec_setround(FE_DEC_TONEAREST);
 
              // print billing amount to file
	fprintf(outp, "%Da\n", b);

        // update sums
              sumM += m;
              sumH += h;
        sumB += b; 
    } // main loop
    
    // close files
    fclose(inp);
    fclose(outp);
 
    // confirm expected quantum in sums
    assert(samequantumd64(sumH, onert));
    assert(samequantumd64(sumB, twort));
 
    // print summary
    printf("SUMMARY:\n");
    printf("  number of calls      = %d\n", n);
    printf("  total minutes        = %Da\n", sumM);
    printf("  total hours billed   = %Da\n", sumH);
    printf("  total amount billed  = %Da\n", sumB);
 
    return 0;
}     

Notes:

  • The quantize functions do the work of rounding to the desired number of places to the right of the decimal point. They return the value of their first argument represented with the quantum exponent of their second argument, rounding if necessary.

  • Mixing decimal FP and integer operands, as in the expression m / 60, is allowed. However, the expression m / 60.0, which mixes decimal and binary FP, would cause an error.

  • On the HP-UX implementation, BID data could be read directly into the decimal FP variable m, without the need of decoding. However, that code would not be portable to systems that use DPD encoding for their decimal FP types.

  • Restoring the default rounding has no effect in this program, except perhaps if the ASCII input had more than 16 decimal digits, but doing so is a good programming practice.

+annotate=structs (New)

The +annotate=structs option annotates the compiled binary with accesses to C/C++ struct fields for use by other external tools such as Caliper. By default, no annotations are added.

+check=lock (New)

The new runtime +check=lock option enables the checking of locking discipline violations; for example, whether appropriate locks are held when threads access shared data in applications using Posix threads. Refer to the online programmer's guide for additional detail and code example. Note that +check=lock is not enabled by +check=all.

+check=thread (New)

The new runtime +check=thread option enables the batch-mode thread-debugging features of HP WDB. This feature requires HP WDB 5.9 or later. The following thread-related conditions can be detected with +check=thread:

  • The thread attempts to acquire a nonrecursive mutex that it currently holds.

  • The thread attempts to unlock a mutex or a read-write lock that it has not acquired.

  • The thread waits (blocked) on a mutex or read-write lock that is held by a thread with a different scheduling policy.

  • Different threads non-concurrently wait on the same condition variable, but with different associated mutexes.

  • The threads terminate execution without unlocking the associated mutexes or read-write locks.

  • The thread waits on a condition variable for which the associated mutex is not locked.

  • The thread terminates execution, and the resources associated with the terminated thread continue to exist in the application because the thread has not been joined or detached.

  • The thread uses more than the specified percentage of the stack allocated to the thread.

The +check=thread option should only be used with multithreaded programs. It is not enabled by +check=all.

+O[no]autopar now supported in C++ Mode (New)

The +O[no]autopar option introduced in version A.06.15 of the compiler was supported only when compiling C or Fortran files. Version A.06.20 also supports this option when compiling C++ files. In addition, specifying +Oautopar now implies the -mt option.

+O[no]dynopt (HP-UX 11.31 only) (New)

On HP-UX 11.31 systems, the +O[no]dynopt option enables [disables] dynamic optimization for the output file. Both forms of this option change the default setting, which allows the run-time environment to enable or disable dynamic optimization according to a system-wide default. This option applies only to executable files and shared libraries, if the run-time environment supports this feature. chatr(1) can be used to change this setting, including restoration of the default setting, after the output file has been created.

+inline_level num (Enhanced)

The format for num is now N[.n], where num is either an integral value from 0 to 9 or a value with a single decimal place from 0.0 to 9.0, as follows:

  • 0   No inlining is done (same effect as the +d option).

  • 1 Only functions marked with the inline keyword or implied by the language to be inlined are considered for inlining.

  • 1.0 < num < 2.0   Increasingly make inliner more aggressive below 2.0.

  • 2 More inlining than level 1. This is the default level at optimization levels +O2, +O3, and +O4.

  • 2.0 < num < 9.0 Increasing levels of inliner aggressiveness.

  • 9 Attempt to inline all functions other than recursive functions or those with a variable number of arguments.

-dumpversion (New)

The -dumpversion option displays the simple version number of the compiler, such as A.06.20. Compare with the -V option, which displays more verbose version information.

#include_next (New)

The #include_next preprocessor directive is similar to the #include directive, but tells the preprocessor to continue the include-file search beyond the current directory, and include the subsequent instance found in the file-search path.

#pragma diag_push (New)

This scoped pragma saves the current severity state of all diagnostics. Subsequent uses of pragmas that modify the severity of a given diagnostic will be in effect within the scope of the diag_push pragma. The effective scope ends with a corresponding #pragma diag_pop. You can specify a #pragma diag_push within the scope of another #pragma diag_push, which results in a new saved severity state and a new effective scope. A compilation unit should have an equal number of #pragma diag_push and #pragma diag_pop uses.

#pragma diag_pop (New)

This pragma restores the severities of all diagnostics to the state prior to the last #pragma diag_push. A compilation unit should have an equal number of #pragma diag_push and #pragma diag_pop uses.

+Oinlinebudget is deprecated (Change)

The +Oinlinebudget option is deprecated in this release and will not be supported in future releases. Use +inline_level.

In next release, default C compilation mode will change from C89 to C99

In the next version of the HP C/aC++ compiler, the default C compilation mode will change from c89 to c99. So cc -Ae or aCC -Ae will be the same as -AC99, and C99 features will be enabled.

Users can prepare for this transition by adding -AC99 to their build options and addressing any issues. Errors that can happen with -AC99 include:

  • enum out of range:

    error #2066: enumeration value is out of "int" range
    error #4041: enumeration value is out of "char" range

  • Restriction on constant expressions:

    error #2057: this operator is not allowed in a constant expression
    error #2028: expression must have a constant value
    Was this:
    warning #4045-D: non-constant initialization performed at runtime

  • Non-static inline can't reference static:

    error #3031-D: an entity with internal linkage cannot be referenced
    within an inline function with external linkage

  • Use of inline or restrict as variables/functions/types. New diagnostics will be added to warn users about the use of inline and restrict in this release (A.06.20). For example:

         4347 %s is a keyword in the C99 C Standard, and its usage as an 
         identifier will  cause an error in C99 mode

In next release, default C++ compilation mode will change to full -AA

In the next version of the HP C/aC++ compiler, the default C++ compilation mode will change from almost -AA to -AA. This will enable -Wc,-ansi_for_scope,on. This is being done to reduce porting efforts by meeting the C++ Standard.

Users can prepare for this transition by adding -AA to their build options and addressing any issues. Errors and warnings (with unintended runtime results) that can happen with -Wc,-ansi_for_scope,on include:

  • Loop index is no longer in scope after the for loop body:

    error #2020: identifier "i" is undefined
  • Reference to outer scope variable instead of loop index:

      warning #2780-D: reference is to variable "i" (declared at line X) --
      under old for-init scoping rules it would have been variable "i"
      (declared at line Y)
    With +wlint:
    warning #3348-D: declaration hides variable "i" (declared at line X)

By also compiling with +We2780, the two errors, 2020 and 2780, should catch any issues resulting from the change in the C++ default.

If you are already using -Aa, this also enables the new default.

Printable version
Privacy statement Using this site means you accept its terms Feedback to webmaster
© 2008 Hewlett-Packard Development Company, L.P.