Jump to content United States-English
HP.com Home Products and Services Support and Drivers Solutions How to Buy
» Contact HP
HP.com home

HP OpenVMS Systems

C Programming Language
Content starts here HP C V7.3 for OpenVMS Alpha Release Notes

HP C V7.3 for OpenVMS Alpha Release Notes


© Copyright 2003, 2007 Hewlett-Packard Development Company, L.P.

Confidential computer software. Valid license from HP required for possession, use or copying. Consistent with FAR 12.211 and 12.212, Commercial Computer Software, Computer Software Documentation, and Technical Data for Commercial Items are licensed to the U.S. Government under vendor's standard commercial license.

The information contained herein is subject to change without notice. The only warranties for HP products and services are set forth in the express warranty statements accompanying such products and services. Nothing herein should be construed as constituting an additional warranty. HP shall not be liable for technical or editorial errors or omissions contained herein.

Intel and Itanium are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

Contents

1 Introduction

This document contains the release notes for HP C V7.3 for OpenVMS Alpha. Note that most online documentation is being provided in html format as well as in its traditional format. The html versions of manuals are provided along with the bookreader versions on the documentation CDROM. The online help files are also available in html format (help cc continues to work in its usual way). The URL to access the online help with a local browser is given at the start of the text-based help cc command. For additional information on the compiler, see also:

  • The HP C User's Guide for OpenVMS systems
  • Enter the command HELP CC

For additional information about the HP C language and its supported library routines, see also:

  • The HP C Language Reference Manual
  • The HP C Run-Time Library Reference Manual for OpenVMS Systems

The release notes for the HP C Run Time Library are contained in the Run Time Components for OpenVMS Alpha.

2 Installation Notes

2.1 Installation Requirements

HP C V7.3 requires OpenVMS Alpha V7.3-2 or higher.

Following are disk space requirements for installation of HP C for OpenVMS Alpha, Block Cluster Size=1:


                                  w/o optional      with optional 
                                  documents         documents 
     Disk space required for      150,000 blocks    250,000 blocks 
     installation: 
 
     Disk space required for      100,000 blocks    160,000 blocks 
     use (permanent): 

For more information about installing the kit, refer to the HP C Installation Guide accompanying these release notes.

2.2 Header Files

The installation kit will replace the DECC$RTLDEF.TLB in SYS$LIBRARY unless it finds that the creation date of the file on this kit is earlier than the creation date of the existing file on your system. Whenever DECC$RTLDEF.TLB is replaced, the kit will also place reference copies of the *.H forms of the headers in
  • SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]
  • SYS$COMMON:[DECC$LIB.REFERENCE.SYS$STARLET_C]

The compiler does not normally search these reference areas, instead it searches for and reads these headers directly from the text library files SYS$LIBRARY:DECC$RTLDEF.TLB and SYS$LIBRARY:SYS$STARLET_C.TLB. The *.H form of the headers are provided as a convenience to users for reference purposes such as searching and browsing, which are not directly supported for text libraries.

2.3 Startup Procedure

HP C for OpenVMS Alpha provides an optional startup procedure, SYS$STARTUP:DECC$STARTUP.COM . This procedure may be invoked by the system startup procedure to perform an install on the compiler and its associated message file to improve compiler performance.

3 Migrating from VAX C to HP C

If you are migrating from VAX C to HP C, you might find the following publication useful:
Compaq C Migration Guide for OpenVMS VAX Systems (Order number: AA-Q5AVA-TE)

This guide is included with the Compaq C for OpenVMS VAX product, to which it primarily applies. However, the following sections of this guide might also prove helpful if you are porting VAX C code to HP C on an Alpha system:

  • The following sections in Chapter 1---Migrating to the Compaq C Run-Time Library:
    • Potential Migration Concerns and Solutions
    • Behavior Differences Between the VAX C RTL and Compaq C RTL
    • Compaq C RTL Obsolete Features
    • Debugging and the Compaq C RTL Object Library
    • Some subsections of C RTL Interoperability Concerns
  • All of Chapter 2---Migrating to the Compaq C Compiler

For more information on Linking to the HP C RTL on OpenVMS Alpha systems, see the section RTL Linking Options on Alpha Systems in Chapter 1 of the HP C Run-Time Library Reference Manual included in your product documentation.

For more information on features helpful in migrating to HP C, see the HP C User's Guide included in your product documentation. Such features include:

  • Command-line qualifiers:
    /STANDARD
    /WARNINGS
    /EXTERN_MODEL
    /[NO]SHARE_GLOBALS
  • Preprocessor directives:
    #pragma message
    #pragma extern_model

The HP C User's guide also contains a "Migrating from VAX C" appendix that you might find useful. This appendix summarizes the features that distinguish HP C for OpenVMS Systems from VAX C Version 3.2. You might also want to read the Common Pitfalls appendix of the user's guide.

Note that while the /STANDARD=VAXC qualifier enables a number of language features and behaviors that aid in building programs developed with the VAX C compiler, it is sometimes the case that differences between the two compiler implementations can produce unexpected behavior differences in the compiled program. Also note that the /STANDARD=VAXC qualifier only affects the language dialect the compiler accepts. The HP C compiler has separate qualifiers that control other environmental characteristics (e.g. /extern_model, /share_globals, and /nested_include) that may affect the ease of building a VAX C code base with HP C.

4 Installing and Using Multiple Compiler Versions

HP C V7.3 X7.3-103 provides limited support for installing and using multiple versions of the compiler on the same node.

During installation of V7.3, if a V6.0 or higher version of the compiler is already installed, you will be given the opportunity to preserve that compiler rather than overwrite it. If you choose to preserve the currently-installed compiler, you will then be given an opportunity to keep the currently-installed compiler as the system default and install the new compiler as an alternate. By default, preserving the currently installed system compiler is performed by making it an alternate compiler, and installing the new compiler as the system default.

The choice to use an alternate compiler instead of the installed system compiler can be made by users, by running a command procedure that changes the behavior of the cc command for the process that invokes it.

4.1 Displaying and selecting the compiler version

This kit provides two command procedures to display and control which C compiler is used by a process.

  • SYS$SYSTEM:DECC$SHOW_VERSIONS.COM
    This procedure displays what C compilers are available on the system, together with their version numbers. It also displays which compiler is the default for the current process. An example:


     
      @SYS$SYSTEM:DECC$SHOW_VERSIONS.COM 
     
      The following C compiler(s) are available 
      in SYS$SYSTEM: 
     
      Filename                      Version 
      -------------------------------------- 
      DECC$COMPILER.EXE             V6.4-005 
      DECC$COMPILER_V06_04-005.EXE  V6.4-005 
      DECC$COMPILER_V06_04-006.EXE  V6.4-006 
      DECC$COMPILER_V06_02-008.EXE  V6.2-008    Process Default 
     
    

  • SYS$SYSTEM:DECC$SET_VERSION.COM
    This procedure either sets up process logicals that point to an alternate C compiler in SYS$SYSTEM and it issues a "$SET COMMAND" to a corresponding cld file in SYS$SYSROOT:[SYSHLP.CC$ALPHA_CLD] to establish the valid set of CC command line options, or else it removes the process logicals and does an appropriate "$SET COMMAND" to revert back to using the default system compiler. The procedure takes one argument, a version number or "SYSTEM" (if no arguments are specified you will be prompted). The SYSTEM argument selects the installed system compiler, which is the one displayed with the filename DECC$COMPILER.EXE in the output of DECC$SHOW_VERSIONS.COM. Alternate compilers are shown in the output of DECC$SHOW_VERSIONS.COM with their version number appended to the simple filename.
    Alternate compilers must be located in SYS$SYSTEM and their names must be based upon the compiler version number. For example the V6.2-008 compiler is given the name: "SYS$SYSTEM:DECC$COMPILER_V06_02-008.EXE".
    To select a compiler, either pass a full ident string or enough of the ident string to be unique. For example: to select the V6.2-008 compiler from our list above we can pass V6.2-008 or V6.2 to the DECC$SET_VERSION.COM routine. In this example, to select a 6.4 compiler, a full ident string would be required to distinguish between the V6.4-005 and the V6.4-006 compilers.


     
    $@SYS$SYSTEM:DECC$SET_VERSION.COM V6.2-008 
     
    $ SHOW LOGICAL DECC$COMPILER* 
     
    (LNM$PROCESS_TABLE) 
     
    "DECC$COMPILER" = 
      "SYS$SYSTEM:DECC$COMPILER_V06_02-008.EXE" 
    "DECC$COMPILER_MSG" = 
      "SYS$MESSAGE:DECC$COMPILER_MSG_V06_02-008.EXE" 
     
    $ @SYS$SSYTEM:DECC$SET_VERSION 6.4 
     
    The following 6.4 Compaq C compiler(s) are available 
    in SYS$SYSTEM: 
     
    Filename                      Version 
    --------------------------------------- 
    DECC$COMPILER.EXE             V6.4-005 
    DECC$COMPILER_V06_04-006.EXE  V6.4-006 
    DECC$COMPILER_V06_04-005.EXE  V6.4-005 
     
     
    Ambiguous version number, please be specify a 
      full version number, ex: V6.4-005 
    Version number : V6.4-005 
     
    $ SHOW LOGICAL DECC$COMPILER 
       "DECC$COMPILER" = 
         "SYS$SYSTEM:DECC$COMPILER_V06_04-005.EXE" 
    $ SHOW LOGICAL DECC$compiler_msg 
       "DECC$COMPILER_MSG" = 
         "SYS$MESSAGE:DECC$COMPILER_MSG_V06_04-005.EXE" 
     
    

    When this procedure is run in a process, subsequent CC commands invoke the selected compiler version (until the procedure is run again). However, when spawning a process, the DECC$SET_VERSION should be re-issued by the spawned process in order to have the spawned process use the correct values in the DCL command table when processing command line qualifiers. Note that MMS spawns processes, so your MMS files should be modified to include a DECC$SET_COMMAND if you are not using the installed compiler when building. The process-level logicals and the "$SET COMMAND" issued by DECC$SET_VERSION do not affect other processes or users on the system.

4.2 Side effects and restrictions on multiple versions

When you install this kit, it provides the latest DECC$RTLDEF.TLB, and the latest documentation, even if you select the option of having the new compiler as the alternate compiler. The new DECC$RTLDEF.TLB does not adversely impact a preexisting V6-based compiler because they are upwardly compatible.

Beginning with the V6.4A (ident V6.4-006) a set of CLD files for all the officially released compilers from V6.0 onward will be placed in SYS$SYSROOT:[SYSHLP.CC$ALPHA_CLD]. The V6.4A CLD file will be inserted into the default system DCL table ONLY if you select the new compiler as the installed compiler. This is in contrast to the original version of V6.4 (ident V6.4-005) which unconditionally updated the DCL tables with a V6.4 CLD file. This is also in contrast to what is stated in the installation guide for V6.4 (The installation guide was not updated to reflect the changes in V6.4A.)

Because of these differences in how CLD files are handled if you have installed V6.4-005 you should reinstall the compiler version which you wish to be the default compiler in order to get the default DCL tables to match your default compiler, and then V6.4A (or a higher version number) may be installed as an alternate compiler. If you are not able to reinstall an old compiler kit, issue a DECC$SET_VERSION <version-num> as a workaround to get the correct command tables. Alternatively, you may ask the system administrator to update the system DCL tables with the correct CLD file from SYS$SYSROOT:[SYSHLP.CC$ALPHA_CLD].

Please remember that if you spawn a process, your DCL tables are not inherited by the spawned process, even though your logical tables are inherited. If you do not re-run DECC$SET_COMMAND (or alternatively issue a "SET COMMAND") your spawned process will use the default DCL tables.

If you have mismatched CLD files you may see some of the following symptoms:

  • If you are accidentally using an old compiler option with a newer CLD file, you will not see an error when a new option is used with an older compiler that does not support it. Instead, the option will be silently ignored. For example, a V6.2 compiler should produce the following error when passed the /first_include qualifier: "%DCL-W-IVQUAL, unrecognized qualifier ...."


      $cc/ver 
        Compaq C V6.2-008 on OpenVMS Alpha G7.3 
      $cc /first_include foo.c  ! /first_include new in 6.4 
      $!No complaint 
      $! use of decc$set_version in your spawed process fixes this 
      $ @SYS$SYSTEM:DECC$SET_VERSION V6.2 
      $cc /first_include foo.c 
        %DCL-W-IVQUAL, unrecognized qualifier - 
        check validity, spelling, and placement 
        \FIRST_INCLUDE\
    
  • If you attempt to use a new compiler with an older CLD file, you will find that the new compiler options are not accepted.


      $ cc /ver 
        Compaq C V6.4-006 on OpenVMS Alpha G7.3 
      $ cc /first_include test.c 
        %DCL-W-IVQUAL, unrecognized qualifier - 
        check validity, spelling, and placement 
      $! use of decc$set_version in your spawed process fixes this 
      $ @SYS$SYSTEM:DECC$SET_VERSION V6.4 
      $ cc /first_include foo.c 
      $!No complaint 
    
  • Another type of error that you may see with mismatched CLD files is a %CLI-F-SYNTAX error followed by a traceback. For example:


      $ cc /arch=ev6_2 test.c 
    %CLI-F-SYNTAX, error parsing 'EV67' 
    -CLI-E-ENTNF, specified entity not found in command tables 
    %TRACE-F-TRACEBACK, symbolic stack dump follows 
     [Tracebacks deleted ] 
    

And because you must have the newest CLD file and header files in order to use the newest compiler, if you run an older installation procedure to put an older compiler back on your system, you must then re-run the V6.4A (or higher) installation to get the newest files.

Note that there are two logical names involved in establishing the compiler version - one for the compiler image and one for its message file. This version of the compiler will issue a diagnostic if it is invoked with the wrong version of the message file - but previous versions of the compiler do not detect this situation. If you find that an older version of the compiler is issuing diagnostics that don't make sense for the code construct they're attached to, or if the message text is missing and only a message number is issued, check that you have matched versions of the files designated by the two logicals using the command "$ show logical decc$compiler*". The response should show matching version-numbered files as in the example selecting the 6.2 compiler. Or if you are using the system compiler, the response should be "%SHOW-S-NOTRAN, no translation for logical name DECC$COMPILER*".

4.3 Installation Procedure Changes

When you install HP C V7.3 on a system that already has a 6.0 or higher compiler installed, you will be given the opportunity to preserve the currently-installed system compiler. To do this, answer yes to the following question (the xxx will be replaced by the full version number of the existing system compiler):


"Should the existing xxx system compiler be preserved [NO]:" 

If you answer no, the installation will procede in the traditional manner, overwriting the currently-installed system compiler.

If you answer yes, you will be asked an additional question. To get the traditional behavior of installing the kit compiler as the system default, answer NO to the question:


"Should this xxx system compiler remain the 
                        default when cc is typed [NO]:" 

Since you have previoiusly asked to preserve the existing system compiler, that compiler is made an alternate compiler before installing the new system compiler from the kit. If you answer yes to the question, the kit compiler will be installed as an alternate compiler and the existing system default compiler will remain the default.

4.4 Sample installation fragment


        Beginning installation of CC V6.5 at 14:26 
 
%VMSINSTAL-I-RESTORE, Restoring product save set A ... 
%VMSINSTAL-I-RELMOVED, Product's release notes moved... 
 
  Compaq C Version V6.5 for OpenVMS Alpha Systems 
 
  Copyright 2002 Compaq Information Technologies Group, L.P. 
 
  Compaq and the Compaq logo are trademarks of Compaq Information 
  Technologies Group, L.P. in the U.S. and/or other countries. 
 
  Confidential computer software. Valid license from Compaq required for 
...etc... 
 
  A C V6.2-008 compiler was found on your system. 
  Type YES to keep this compiler on your system 
  either as the default system compiler, or as an 
  alternate compiler.  Type NO to supersede C V6.2-008. 
 
* Should the existing V6.2-008 system compiler 
   be preserved [NO]: yes 
 
 
  Type NO to have the compiler on this kit become the 
  default system compiler and to have the currently 
  installed compiler saved as an alternate compiler. 
  Type YES to keep the current system compiler as the 
  default compiler, and to have the compiler on this 
  kit available as an alternate compiler.  Alternate 
  compilers can be invoked with the cc command after 
  invoking SYS$SYSTEM:DECC$SET_VERSION.COM passing 
  a version_number. 
 
* Should this V6.2-008 system compiler remain the 
   default when cc is typed [NO]: no 
 
 
        Product:      C 
        Producer:     DEC 
        Version:      6.5 
        Release Date: 01-NOV-2001 

5 Enhancements and bug fixes

5.1 Enhancements in V7.3

This version is largely a bug-fix release, the list of bugs fixed is given in Section 5.16. There are only two new features, which are intended to make it more command-line compatible with the corresponding C compiler version for I64:
  • The /CHECK qualifier now accepts optional keywords ALL and NONE. This is for consistency with similar qualifiers and other VMS compilers. It permits all checks except for named ones to be enabled, without needing to specify the names of all supported checks. E.g. /CHECK=(ALL,NOBOUNDS) enables all run-time checking code except for bounds checking.
  • The new I64-only /CHECK=ARG_INFO qualifier is recognized and ignored (with optional QUALNA diagnostic). This is intended to help support maintenance of common build scripts for Alpha and I64.

5.2 Enhancements in V7.1

This version contains the following new features and enhancements:

  • New builtins for I64 compatibility.

    The __CMP_STORE_* builtins are not fully functional on I64, and should be considered deprecated. New builtin functions __CMP_SWAP*, _InterlockedCompareExchange*, and __RETURN_ADDRESS have been added for source compatibility with the I64 compiler. See <builtins.h> for prototypes.

    The Alpha architecture has the somewhat unusual concept of a "lock region" in the load-locked/store-conditional paradigm used to implement atomic update sequences. This concept is exposed by the __CMP_STORE_* builtin functions, which have the ability to test a value from one location, and store a new value into a different location in the same lock region with guaranteed atomicity. On IA64, there is no lock region wider than the location being updated, so the __CMP_STORE_* builtins can only be implemented sensibly in the case that the source and destination addresses are identical. That case can be implemented efficiently using the IA64 cmpxchg instructions.

    To promote source compatibility for these kinds of low-level locks, the __CMP_STORE_* builtins are considered deprecated. They continue to work on Alpha, but on I64 they give an error unless the compiler can determine that the source and destination addresses are the same, in which case they give a warning. The most compatible replacements for existing uses of __CMP_STORE_* are the new __CMP_SWAP_* builtins, which have similar prototypes except that the destination parameter has been removed since the source and destination are identical by definition.

    But there are also new builtins with names and signatures matching those provided by Intel's IA64 compiler, _InterlockedCompareExchange*. Instead of returning a status value, these return the value fetched. If it matches the comparison value passed in, then the new value was stored; otherwise the store did not take place and the code has the value that blocked the store (this value cannot be determined when using either the __CMP_SWAP_* or __CMP_STORE_* builtins). There are four variations of this builtin, two for longword updates (*Exchange_*) and two for quadword updates (*Exchange64_*). All return the old value as unsigned __int64, and take the new value as unsigned __int64, regardless of whether the location to update is longword or a quadword. Also note that the order of the comparand and new_value parameters are reversed relative to the __CMP_STORE_*/__CMP_SWAP_* builtins.

    For each update size there are two variations, "_acq" and "_rel", corresponding to IA64 "acquire" and "release" semantics for the cmpxchg instruction. On Alpha, the *_acq forms generate a memory barrier AFTER the conditional store, while the *_rel forms generate a memory barrier BEFORE the conditional store. Note that the __CMP_SWAP_* builtins also have "_ACQ" and "_REL" forms, even though the __CMP_STORE_* builtins do not. The forms of __CMP_STORE_* and __CMP_SWAP_* with neither "_ACQ" nor "_REL" suffix do not generate any memory barrier.

    Finally, there is a __RETURN_ADDRESS builtin. On Alpha it returns the value in R26 on entry to the current function, and on I64 it returns the value in B0 on entry to the current function. This builtin cannot be used in functions with non-standard linkage (#pragma linkage).

  • #pragma linkage enhancements.

    #pragma linkage is implicitly target-specific because it names machine registers, and interacts with the calling standard on the target machine. However, to assist in porting significant source code bases that used the pragma without conditionalizing the use to Alpha, the I64 compiler recognizes #pragma linkage, assumes it was intended for Alpha, and attempts to map the Alpha machine registers to corresponding IA64 registers under the calling standard for OpenVMS I64. This was done to ease porting, but ideally code using the pragma should have been conditionally compiled for Alpha.

    For use in new code, two variations of the pragma have been added, #pragma linkage_alpha and #pragma linkage_ia64. These pragmas are explicitly defined to be target-specific and are never mapped to a different target - they are ignored with an informational message if encountered on a different target machine than the one they specify.

    Also, all three forms of the pragma recognize a new keyword, "standard_linkage" , which tells the compiler to use the normal linkage conventions appropriate to the target platform, as specified in the calling standard. When standard_linkage is specified, it must be the only option in the parenthesized list following the linkage name. This can be useful to confine conditional compilation to the pragmas that *define* linkages, without requiring the corresponding use_linkage pragmas to be conditionally compiled as well, as shown below.

    Code that is written to use linkage pragmas as intended, treating them strictly as target-specific without implicit mapping, might have a form like this:


         #if defined(__alpha) 
         #pragma linkage_alpha special1 = (__preserved(__r1,__r2)) 
         #elif defined(__ia64) 
         #pragma linkage_ia64 special1 = (__preserved(__r9,__r28)) 
         #else 
         #pragma message ("unknown target, assuming standard linkage") 
         #pragma linkage special1 = (__standard_linkage) 
         #endif 
    


  • New keyword TARGET for /MMS_DEPENDENCIES qualifier.

    The keyword TARGET may be used with an optional value to specify the name of the "target" in the generated dependency file output. By default, the target name is the simple name of the primary source file, with the file extension changed to .OBJ. If a value is provided for target, then the simple filename and extension parsed from that string is used as the name of the target. As a special case, if the value of TARGET is .OBJ, then the target name will be the simple name and extension of the object module produced by the compilation (which might be controlled by the /obj qualifier). For example:


    CC/MMS/OBJ=OUTPUT DISK:[DIR]T.C 
    produces an MMS file with 
    T.OBJ : 
     
    CC/MMS=(TARGET=DISK:[DIR]FOO)/OBJ=OUTPUT T.C 
    produces an MMS file with 
    FOO : 
     
    CC/MMS=(TARGET=.OBJ)/OBJ=DISK:[DIR]OUTPUT T.C 
    produces an MMS file with 
    OUTPUT.OBJ : 
    


  • Improved diagnostics for some C99 features including flexible array member (a struct whose last member has an incomplete array type).

  • Support enum types containing values beyond the range of type int. Under /stand=relaxed, the compiler now supports this extension commonly used in open source code.

  • New diagnostics to report unreferenced labels, with unreferenced case labels spelled the same as a visible enumeration constant reported by default. Others can be enabled by the "questcode" or "unused" message groups.

  • Better diagnostic for a mismatched comment delimiter (i.e. the character sequence "*/" appearing outside of a comment, string literal, or character constant).

  • Better, more complete and accurate information in the BADANSIALIAS diagnostic.

  • The /NAMES=LOWERCASE command line qualifier has no real practical value, as the only treatments of casing for global names on VMS that make sense are UPPERCASE and AS_IS. Therefore this variation is no longer supported - using it produces a warning message, and global names are processed as if /NAMES=AS_IS had been specified.

  • The /STANDARD= command line qualifier now enforces the documented behavior that there is no default keyword value supplied when the qualifier is explicitly present. Although this qualifier was not intended to have a default value when specified explicitly, the behavior of previous compilers has been to treat /STANDARD the same as /STANDARD=ANSI89, which is the strict C89 mode. Note this differs from the documented default when /STANDARD is omitted altogether, which is /STANDARD=RELAXED. Beginning with this version, specifying /STARDARD without supplying a keyword will result in "%DCL-W-VALREQ" from DCL, and the compiler will not be invoked.

  • The /STANDARD= command line qualifier now accepts a new keyword value, "LATEST". This keyword selects the strict mode of the latest version of the C standard that has been implemented by the compiler. In V7.1, this is equivalent to /STAND=C99.

  • The STRCTPADDING diagnostic is an optional diagnostic to detect padding inserted by the compiler between members of a struct to satisfy alignment requirements. The purpose is to alert the user that changing the order of the members could save space. A new optional message, STRCTPADEND, has been added at user request to help detect possible size differences in structs compiled on other platforms.

  • Diagnostic messages reported against source code in a header file that is actually contained within a text library module now provide the name of the module in the library as well as the filespec for the library.

  • New command line qualifier /ACCEPT=[NO]TRIGRAPHS. Controls whether the compiler recognizes trigraphs, independently of the /STANDARD qualifier, although the /STANDARD qualifier controls the default: COMMON and VAXC modes default to /ACCEPT=NOTRIGRAPHS, all other modes default to /ACCEPT=TRIGRAPHS.

  • A new option to the /POINTER_SIZE=LONG qualifier is available. When /POINTER_SIZE=LONG=ARGV is specified, the argv argument to main will be comprised of long pointers instead of short pointers. This can make using long pointers easier because the pointer size of argv will match the default pointer size for the compilation.

  • A command procedure CC$PRODUCT_REMOVE has been added to the HP C V7.1 kit for OpenVMS Alpha. This procedure allows you to remove the HP C compiler product. It performs the equivalent of a PCSI PRODUCT REMOVE command.
    You are required to disable the product license before issuing the command procedure to prevent a compilation from interfering with the delete process.
    If the compiler has been installed as a shared image, the command procedure will uninstall the image.
    The command procedure takes no parameters and can be run as follows:


    $ @SYS$SYSTEM:CC$PRODUCT_REMOVE 
     
    Do you wish to proceed with removing HP C <No>? Yes [Ret] 
    

    Enter "Yes" to remove the compiler from your system.

5.3 Enhancements in V6.5

This version contains the following new features and enhancements:

  • Uses GEM BL48 backend, with best support for EV7 processors.

  • Optional "_nm" suffix can be appended to any #pragma name to prevent macro expansion on that pragma. This is the opposite of the "_m" suffix introduced in V6.4.

  • C99 _Pragma operator, which effectively allows pragma directives to be produced by macro expansion. Note: when specified using this operator, the tokens of the pragma, which appear together within a single string literal in this form, are not macro expanded, regardless of any suffix. But macro expansion can be accomplished if desired by using the stringization operator to form the string. For specifics on this and the other C99 features, the C99 standard is the best source - see Section 5.5 for information on getting a copy.

  • C99 constants for specific values of Infinity and NaN are supported (only when using /float=ieee). The underlying implementation-specific identifiers for these constants are:


        __decc_float_ieee_Infinity 
        __decc_float_ieee_NaN 
        __decc_double_ieee_Infinity 
        __decc_double_ieee_NaN 
        __decc_long_double_ieee_Infinity 
        __decc_long_double_ieee_NaN 
    


  • C99 adjacent string concatenation. Wide and normal strings can be mixed, in which case the normal strings get promoted to wide and a wide result is produced.

  • C99 Universal Character Names (UCNs) are accepted in identifiers, string literals, and character constants (and their wide variations).

  • New #pragma include_directory has been added. The syntax is:


        #pragma include_directory <string-literal> 
    

    The effect of each include_directory pragma is as if its string argument (including the quotes) were appended to the list of places to search that is given its initial value by the /INCLUDE_DIRECTORY qualifier, except that an empty string is not permitted in the pragma form. It is intended to ease DCL command line length limitations when porting applications from POSIX-like environments built with makefiles containing long lists of -I options specifying directories to search for headers. Just as long lists of macro definitions specified by the /DEFINE qualifier can be converted to #define directives in a source file, long lists of places to search specified by the /INCLUDE_DIRECTORY qualifier can be converted to #pragma include_directory directives in a source file.

    Note that the places to search as described in the help text for the /INCLUDE_DIRECTORY qualifier includes the use of POSIX-style pathnames, e.g. "/usr/base", and that this form can be very useful when compiling code that contains POSIX-style relative pathnames in #include directives. For example, #include <subdir/foo.h> can be combined with a place to search such as "/usr/base" to form "/usr/base/subdir/foo.h", which will be translated to the filespec "USR:[BASE.SUBDIR]FOO.H"

    Note that this directive can only appear in the main source file, or in the first file specified in the /FIRST_INCLUDE qualifier. It also must appear before any #include directives.

  • New keywords NOCRTL and RESTORE_CRTL have been added to #pragma extern_prefix. These keywords control whether or not the compiler will apply its default RTL prefixing to the names specified on the pragma. The effect of NOCRTL is like that of the except= keyword of the /prefix_library_entries command line qualifier. The effect of RESTORE_CRTL is to undo the effect of a NOCRTL or a /prefix=except= on the command line.

  • /ANNOTATIONS command line qualifier


        /ANNOTATIONS=(option[,...])   D=/NOANNOTATIONS 
        /[NO]ANNOTATIONS 
    

    Controls whether or not the source listing file is annotated with indications of specific optimizations performed or, in some cases, not performed. These annotations can be helpful in understanding the optimization process.
    If annotations are requested (and the /LISTING qualifier appears on the command line), the source listing section is shifted to the right and annotation numbers are added to the left of source lines. These numbers refer to brief descriptions which appear later in the source listing file.
    Keywords selecting annotation of specific optimizations are:
    • ALL - Selects all annotations. This output can be quite verbose, as it includes detailed output for all annotations. For more concise output for each kind of annotation, use /ANNOTATIONS=(ALL,NODETAIL), or just /ANNOTATIONS with no keywords.
    • [NO]CODE - Annotates machine code listing with descriptions of special instructions used for prefetching, alignment, etc. Note that /MACHINE_CODE must also be specified in order for this keyword to have any visible effect.
    • [NO]DETAIL - Provides additional level of annotation detail, where available.
    • [NO]FEEDBACK - Indicates use of profile-directed feedback optimizations. Note that feedback optimizations are not implemented on OpenVMS, so this keyword has no visible effect.
    • [NO]INLINING - Indicates where code for a called procedure was expanded inline.
    • [NO]LOOP_TRANSFORMS - Indicates optimizations such as loop reordering and code hoisting.
    • [NO]LOOP_UNROLLING - Indicates where advanced loop nest optimizations have been applied to improve cache performance (unroll and jam, loop fusion, loop interchange, etc).
    • [NO]PREFETCHING - Indicates where special instructions were used to reduce memory latency.
    • [NO]SHRINKWRAPPING - Indicates removal of code establishing routine context when it is not needed.
    • [NO]SOFTWARE_PIPELINING - Indicates where loops have been scheduled to hide functional unit latency.
    • [NO]TAIL_CALLS - Indicates an optimization where a call from routine A to B can be replaced by a jump.
    • [NO]TAIL_RECURSION - Indicates an optimization that eliminates unnecessary routine context for a recursive call.
    • NONE - is the same as /NOANNOTATIONS.

    Specifying /ANNOTATIONS with no keywords is the same as specifying /ANNOTATIONS=(ALL,NODETAIL)

  • More aggressive /OPT=INLINE=ALL
    The heuristics controlling inlining have been changed in this release to provide overall better performance for the AUTOMATIC, SIZE, and SPEED inlining controls. Because these improvements rely on improvements in the compiler's ability to perform inlining in more situations, a side effect is that /OPT=INLINE=ALL has become more aggressive than it was in previous releases. Consequently, programs that had previously been compiled with /OPT=INLINE=ALL may now cause the compiler to exhaust virtual memory or take an unacceptably long time to compile. /OPT=INLINE=ALL was noted as not recommended for general use when it was introduced in V5.0. That recommendation is even stronger in this release. Programs that were measured as benefitting from /OPT=INLINE=ALL with a previous release, but which no longer can be compiled within reasonable resource limits with this release should generally be changed to use /OPT=INLINE=SPEED.

5.4 Enhancements in V6.4A

This version does not provide new functionality over V6.4, but rather it provides significant compiler bug fixes, usability improvements for multi-version support, and changes to signal.h to ease its use with /pointer_size=long. See Section 5.19 for the bugs fixed. It also uses a slightly newer version of the GEM backend, with miscellaneous tuning changes.

5.5 Enhancements in V6.4

In addition to the support for installing multiple compiler versions, this release provides most language-feature support for the new C99 standard, ANSI/ISO/IEC 9899:1999. This was published by ISO in December, 1999 and adopted as an ANSI standard in April, 2000.

Note that an official copy of the standard can be purchased and downloaded as a PDF file for less than $20US from either NCITS or ANSI .

This release also adds new command line options and pragmas, a new version of the GEM optimizing backend for Alpha, three new C99 header files, and many new functions in the <math.h> header.

Note that some of the "new" run-time library support for C99 is available in earlier versions of OpenVMS through extensions that had already been implemented:

  • many of the math routines in math.h that are conditionally excluded when compiling in strict ANSI89 mode match functions that were added in the C99 standard
  • many library routines for complex data types (other than long double complex) are available because they are the same as used for the Fortran complex data types, and the Alpha calling standard makes them callable from either language.

And although full support for all C99 library features is not anticipated until an OpenVMS release after the "7.3" release currently in field test, the 7.3 field test release does provide the new C99 math library functions that were not already available as extensions, and it supports the long double complex data type.

Important Note: The following three changes will impact existing code.

  • The <math.h> header supplied on this kit declares prototypes for all of the new C99 math functions, conditionalized to using Compaq C version 6.4 or greater, and to a language mode that sets the macro __STDC_VERSION__ >= 199909. As described later, this macro is set in most language modes, including the default "relaxed_ansi" mode. This is in concert with the next change noted, involving prefixing of C99 entries. If your existing code declares an external identifier that is the same as the identifier for one of the many new math or complex functions added in C99, and your program #includes <math.h> (or the new <complex.h> ), then you will get a compile-time error if your declaration is incompatible with the standard declaration. If your code encounters a compile-time conflict with the declarations in math.h, you should rename the identifier in your code, as it will become a long-term burden to portability. Basically, the C standard specifies that external names declared in standard headers are reserved for that use regardless of whether or not the header is #included. Because the platform will be supporting the C99 standard, and the default "relaxed" language mode of the compiler will enable all of C99, we are forcing the namespace issue at compile-time and with facility prefixing, even though not all functions may be available at link time in currently-shipping OpenVMS libraries.

  • The new default of /PREFIX=C99_ENTRIES for the default language mode of /STANDARD=RELAXED may cause unresolved references at link time if your application provides its own implementation of library functions that have been added to C99. Workarounds are to specify /PREFIX=ANSI_C89_ENTRIES explicitly, rename your function (especially if it does not exactly implement the behavior required by C99), or recompile both your function definition and its callers. In the latter case, you will need to remove your own implementation when the supported version of the new function becomes available in the Compaq C RTL.

  • The new rules for determining the type of an integer constant could lead to some constants in your program being interpreted as having a signed type when previous compiler versions gave them an unsigned type. This could affect your program's behavior in subtle ways. The new message intconstsigned can be enabled to report constants in your source code that are being treated differently under the C99 rules than they were in previous releases. This message is also part of the new message group newc99 . If your program relied on unsigned treatment, the simple fix is to add the correct suffix including a "U" or "u" to force the constant to have the expected type. Such a change would be backward compatible and portable.

The following specific enhancements were made:

  • New C99 hexadecimal form of floating-point constants

    This form of constant permits floating point values to be specified reliably to the last bit of precision. It does not specify a bit pattern for the representation. Instead it is interpreted much like an ordinary decimal floating point constant except that the significand is written in hexadecimal radix, and the exponent is expressed as a decimal integer indicating the power of two by which to multiply the significand. A "P" instead of an "E" separates the exponent from the significand. Thus, for example, 1/2 can be written as 0x1P-1 or 0x.1P3. The C99 standard also adds printf/scanf specifiers for this form of value, but that support will not be present in OpenVMS run-time libraries until after the 7.3 release.

  • New C99 header <stdbool.h> , and keyword _Bool

    This header is intended to be used to access the new C99-specified boolean type _Bool. It defines a macro spelled "bool" that expands to _Bool, intended to be the preferred way to refer to the type. The type is not recognized in VAXC, COMMON, or the strict ANSI89 mode. An object of this type occupies one byte and is an unsigned integer, but its value can only be either 0 or 1. It is permitted to use _Bool as the type for a bit-field. When a value of any scalar type (any arithmetic type including floating point and the new complex types, or any pointer type) is converted to _Bool, the result is zero if the value would compare equal to 0 (e.g. if the pointer is NULL), and otherwise the result is 1. The content of the header is simply as follows:


    #define bool _Bool 
    #define true 1 
    #define false 0 
    #define __bool_true_false_are_defined 1 
    


  • New C99 header <complex.h> and keyword _Complex

    C99 introduces builtin complex data types similar to the Fortran type, in all three precisions (float _Complex, double _Complex, and long double _Complex). The header file <complex.h> defines a macro spelled "complex", intended to be the preferred way to refer to the types. The details of this type can be obtained from the C99 standard and the Language Reference Manual, and by examining the content of the header. Basically the type is similar to the Fortran type in its use. There is no special syntax for constants - instead there is a new keyword "_Complex_I", which has a complex value whose real part is zero and whose imaginary part is 1.0. The header file defines a macro "I" that expands to "_Complex_I", and so a complex constant with equal real and imaginary parts of 2.0 would be written "2.0 + 2.0*I".

    There are some known issues with complex types as follows:
    • The complex data types are not available when using the /float=d_float command line option. This is a permanent restriction.
    • On current versions of OpenVMS, the complex types and functions other than long double complex are available, but the long double complex type is available only in the 7.3 field test.
    • In this version of the compiler, the C99 functions cabs, cabsf, and cabsl cannot be used. This is a temporary restriction. Functions named cabs, cabsf, and cabsl have traditionally been declared in <math.h> using a struct representation to hold two floating values. This is not compatible with the calling standard for passing complex values, or with the implementation of C99 complex data types. In this version of the compiler, the traditional <math.h> declarations are preserved. If you #include <complex.h> in the same compilation as <math.h>, then if <math.h> occurs first you will get an informational message from <complex.h> noting the incompatibility. If you #include <complex.h> prior to the #include <math.h>, then there is no diagnostic, but if you call these functions the generated code will not properly access C99 versions of them. A workaround is to write your own separately-compiled routines that take a pair of parameters of the corresponding real floating point type, and return sqrt(p1*p1 + p2*p2). These routines can then be called with a complex argument.


  • New C99 header <tgmath.h>

    This header provides "type-generic" names for 60 math functions that provide operations for a number of different types, letting the actual argument types select the function to call instead of requiring the user to name the exact function and pass it appropriate arguments. E.g. where C89 defined two different names for the sqare root function (sqrt and sqrtl for double and long double arguments) and reserved a third name (sqrtf for float arguments), C99 defines six names because it requires that the float version be implemented and adds three new complex types (csqrt, csqrtl, and csqrtf). These names are all declared in <math.h> and <complex.h> and can be used in the traditional way. But by including this new header (which internally includes both math.h and complex.h), a call to sqrt(x) will be translated to call the appropriate function according to the type of x. For details, see the standard, the documentation, and the contents of the header.

    Known issue:
    • The type-generic implementation of the absolute value function (fabs) is not available for complex types in this release. You must use the type-specific names (cabs, cabsf, cabsl) instead.


  • Language modes, /STANDARD=C99 , message groups, /PREFIX

    The compiler's default language mode remains /STANDARD=RELAXED_ANSI89, which accepts nearly all language extensions as well as standard C89 and C99 features. It excludes only K&R ("common" mode), VAX C, and Microsoft features that conflict with standard C. The /STANDARD=ANSI89 mode continues to implement strictly the 1990 ANSI/ISO C standard (commonly called C89), issuing all required diagnostics as well as a number of optional diagnostics that help detect source code constructs that are not portable under the C89 standard (digraphs from the 1994 Amendment are also recognized in this mode, even though they were not specified in the 1990 standard). The ISOC94 keyword can still be added to any of the modes (except VAXC) to predefine the macro __STDC_VERSION__, as specified in Amendment 1 to the C89 standard.

    A new mode, /STANDARD=C99, has been added that accepts just the C99 language without extensions, and diagnoses violations of the C99 standard. Since C99 is a superset of Amendment 1, and since the default mode of RELAXED_ANSI89 is a superset of C99, the macro __STDC_VERSION__ will now normally be defined with the C99-specified value of 199901L. Only in the case of adding the ISOC94 keyword to the strict ANSI89, MIA, or COMMON modes will the macro take on the Amendment 1 value of 199409L (in the absence of the ISOC94 keyword, these modes do not define the macro at all).

    Since the standard is quite new, use of C99 features is not really portable in a practical sense yet. Also, the term "ANSI C" or "standard C" will be ambiguous for some time to come (i.e. do you mean C89 or C99). To help with this situation, the compiler has added three new message groups for messages that report the use of features in the following categories:


    noc89  - features not in C89 
    noc99  - features not in C99 
    newc99 - features that are new in C99. 
    

    The existing group, noansi , which is now somewhat ambiguous in name, is retained as a synonym for noc89.

    In recognition of the additional run-time library functions specified in C99, the /PREFIX_LIBRARY_ENTRIES qualifier accepts a new keyword value, C99_ENTRIES. This will enable DECC$ prefixing of all those external names that are specified in C99 (these are a superset of the external names prefixed under /PREFIX=ANSI_C89_ENTRIES and a subset of those prefixed under /PREFIX=ALL_ENTRIES). The /STANDARD=C99 qualifier causes this option to default to /PREFIX=C99_ENTRIES. But note that, as mentioned previously, new C99 run-time library functions will not be available until OpenVMS Alpha releases after V7.3. The compiler will prefix C99 entries based on their inclusion in the standard, not on the availability of their implementations in the run-time library. So calling functions introduced in C99 that are not yet implemented in the Compaq C RTL will produce unresolved references to symbols prefixed by DECC$ when the program is linked.

  • C99 changes to types of integer constants
    The C99 standard introduces the type long long int (both signed and unsigned) as a standard integer type whose range of values requires at least 64 bits to represent. Although Compaq C on Alpha implemented the type long long as an extension many releases ago, the compiler followed the C89 rules for determining the type of an integer constant. Those rules specified that an unsuffixed decimal integer with a value too large to be represented in a signed long would be given the type unsigned long . Compaq C followed this rule and gave a constant too large for signed long the type unsigned long if it would fit, and only gave it a long long type if the value was too large for unsigned long .

    In standardizing the long long type, C99 regularized these rules and made them extensible to longer types. In particular, unsuffixed decimal integer constants are given the smallest signed integer type that will hold the value (the minimum type is still int ). If the value is larger than the largest value of signed long long , then it is given the next larger implementation-defined signed integer type (if there is one). Otherwise the behavior is undefined. Since Compaq C does not implement a signed integer type longer than long long , it will use the type unsigned long long next, with a portability warning. The only portable way to specify a decimal constant that will be given an unsigned type is to use a suffix containing " u " or " U ".

    Compaq C will continue to use the C89 rules in VAXC, COMMON, and strict ANSI89 modes (including MIA), but use the new C99 rules in all other modes. The complete C99 rules are as follows:


    The  type  of  an integer constant is the first of the 
    corresponding list in which its value can be represented. 
     
                 |                       | Octal or Hexadecimal 
    Suffix       |   Decimal Constant    |       Constant 
    -------------+-----------------------+----------------------- 
    none         |int                    |int 
                 |long int               |unsigned int 
                 |long long int          |long int 
                 |                       |unsigned long int 
                 |                       |long long int 
                 |                       |unsigned long long int 
    -------------+-----------------------+----------------------- 
    u or U       |unsigned int           |unsigned int 
                 |unsigned long int      |unsigned long int 
                 |unsigned long long int |unsigned long long int 
    -------------+-----------------------+----------------------- 
    l or L       |long int               |long int 
                 |long long int          |unsigned long int 
                 |                       |long long int 
                 |                       |unsigned long long int 
    -------------+-----------------------+----------------------- 
    Both u or U  |unsigned long int      |unsigned long int 
    and l or L   |unsigned long long int |unsigned long long int 
    -------------+-----------------------+----------------------- 
    ll or LL     |long long int          |long long int 
                 |                       |unsigned long long int 
    -------------+-----------------------+----------------------- 
    Both u or U  |unsigned long long int |unsigned long long int 
    and ll or LL |                       | 
    -------------+-----------------------+----------------------- 
     
    If an integer constant cannot be represented by any type  in 
    its  list,  it  may  have  an  extended integer type, if the 
    extended integer type can represent its value.   If  all  of 
    the  types  in  the  list  for  the constant are signed, the 
    extended integer type shall be signed.  If all of the  types 
    in  the  list  for  the  constant are unsigned, the extended 
    integer type shall be unsigned.  If the list  contains  both 
    signed  and unsigned types, the extended integer type may be 
    signed or unsigned. 
     
     
    


  • #pragma names
    This pragma offers the same kinds of control over the mapping of external identifiers into object module symbols as does the command line qualifier /NAMES, and it uses the same keywords (except that the "lowercase" keyword is not supported). But as a pragma, the controls can be applied selectively to regions of declarations. The pragma has a save/restore stack that is also managed by #pragma environment , and so it is well-suited to use in header files. The effect of " #pragma environment header_defaults " is to set NAMES to "uppercase,truncated", which is the compiler default.

    One important use for this feature is to make it easier to use command line option /NAMES=AS_IS . Both the C99 standard and the C++ standard require that external names be treated as case-sensitive, and 3rd party libraries and Java native methods are starting to rely on case-sensitivity (C99 requires a minimum of 31 characters significant, while C++ requires all characters significant). Therefore we expect the use of /NAMES=AS_IS to become much more widespread.

    The Compaq C run-time library was implemented with all symbols duplicated and spelled both in uppercase and lowercase to allow C programs compiled with any of the /NAMES= settings to work. But traditional practice on OpenVMS combined with compiler defaults of /NAMES=UPPER has resulted in nearly all existing object libraries and shared images to contain all uppercase names (both in references and in definitions), even though C source code using these libraries typically declares the names in lowercase or mixed case. Usually, the header files to access these libraries contain macro definitions to replace lowercase names by uppercase names to allow client programs to be compiled /NAMES=AS_IS. But macro definitions are problematic because every external name has to have a macro.

    The new pragma allows header files to specify just once that the external names they declare are to be uppercased in the object module, regardless of the NAMES setting used in the rest of the compilation. The NAMES setting in effect at the first declaration of an external name is the one that takes effect, thus the setting specified in a header file will not be overridden by a subsequent redeclaration in the user's program (which might specify a different NAMES setting). Note that the automatic Prologue/Epilogue header file inclusion feature described in section 1.7.4 of the User's Guide (in connection with pointer_size pragmas) can also be used to specify the NAMES setting for all headers in a given directory or text library, without having to edit each header directly.


     
    Syntax: 
     
    #pragma names <stack-option> 
    #pragma names <case-option>[, <length-option>] 
    #pragma names <length-option>[, <case-option>] 
     
    Where <stack-option> is one of: 
     
        save      - save the current names state 
        restore   - restore a saved names state 
     
    <case-option> is one of: 
     
        uppercase - uppercase external names 
        as_is     - do not change case 
     
    and <length-option> is one of 
     
        truncated - truncate at 31 characters 
        shortened - shorten to 31 using CRC 
     
    


  • Change to #pragma optimize
    An important change was made to the behavior of #pragma optimize , which was introduced in V6.2 The pragma is no longer controlled by #pragma environment . It still supports the save and restore keywords, but its state is completely separate from the state managed by #pragma environment . In addition, it has a new keyword, command_line . This keyword causes the optimization settings to revert to what was in effect at the start of the compilation, as specified by the CC command line qualifiers.

  • New command line qualifier /FIRST_INCLUDE
    This qualifier lists one or more header file specifications that are to be included before the first line of the main source file. Each header specification is treated as if it appeared within quotes on a #include directive before the first line of source. The headers are included in the order they are specified. This qualifier can be particularly useful to shorten CC command lines with lengthy /DEFINE and/or /MESSAGE qualifiers, by converting them to equivalent #define and #pragma message directives in a file specified by /FIRST_INCLUDE .


    Syntax: 
     
        /FIRST_INCLUDE=(file[,...]) 
        /NOFIRST_INCLUDE (D) 
    


  • New " _m " suffix forces pragmas to expand macros
    As specified in the Language Reference Manual, there is a fixed "grandfathered" list of #pragma directives that always undergo macro expansion in the preprocessor before being translated. No other #pragma directives normally undergo macro expansion. But since there are sometimes circumstances where macro expansion is needed on a particular instance of a pragma, a general mechanism has been added such that spelling the name of a #pragma directive with a trailing " _m " suffix will cause that directive to undergo macro expansion. An example of use follows in the next bullet item for #pragma assert non_zero . The suffix is permitted on all pragmas, including those that are already specified as undergoing macro expansion (in which case it has no effect).

  • New non_zero keyword for #pragma assert
    This new keyword allows you to assert that a particular constant-expression must be non-zero at compile time, and supply a text string to be output if the assertion proves false. The text string is output with a warning message that includes the source text of the expression.


     
    Syntax: 
       #pragma assert non_zero(<constant-expression>) 
                                                 <string-literal> 
     
    

    Note that the constant-expression is a C language constant-expression, not just a preprocessor #if expression. And while #pragma assert itself does not perform macro expansion, the alternate form #pragma assert_m can be used to cause macro expansion to take place, which is most often what is desired, as in the second example below (since "offsetof" is a macro).


     
    Example: 
       #pragma assert   non_zero(sizeof(a) == 12) "wrong size a" 
       #pragma assert_m non_zero(offsetof(s,b)==4) "wrong offset b" 
     
    

    If the sizeof a is not 12, and the offset of member b in the struct named by type b is not 4, the following diagnostics are output:


     
     CC-W-ASSERTFAIL, The assertion "(sizeof(a) == 12)" 
        was not true. wrong size a. 
     CC-W-ASSERTFAIL, The assertion "(offsetof(s,b) == 4)" 
        was not true. wrong offset b. 
     
    


  • New #pragma unroll
    This pragma controls the amount of loop unrolling performed on a subsequent for loop.


     
    Syntax: 
     
      #pragma unroll (unroll_factor) 
     
    Example: 
     
      #pragma unroll (1) 
      for (i=0; i<1000; i++) {foo(i);} 
     
    

    The unroll pragma directs the compiler to unroll the for loop that follows it by the number of times specified by the unroll_factor argument. The directive must be immediately followed by the for statement it is to control, otherwise a warning is issued and the pragma is ignored. The unroll_factor is an integer constant in the range from zero to 255. Using a value of zero will cause the directive to be ignored and the compiler will determine the number of times to unroll the loop in its normal way. Using a value of one will prevent the loop from being unrolled.

  • New use of static keyword in array bounds.
    C99 permits the keyword " static " to be used within the outermost array bound of a formal parameter in a prototype function declaration. The effect is to assert to the compiler that at each call to the function, the corresponding actual argument will provide access to at least as many array elements as are specified in the declared array bound. Consider the following two function definitions:


     
    void foo(int a[1000]){ ... } 
    void bar(int b[static 1000]) { ... } 
     
    

    The declaration of foo is absolutely equivalent to one that declares "a" to be "int *". When compiling the body of foo, the compiler has no information about how many array elements may exist. The declaration of bar differs in that it asserts to the compiler that it may assume that at least 1000 array elements exist and may be safely accessed. The intent is to provide a hint to the optimizer about what can be safely pre-fetched.

  • New type keyword _Imaginary
    C99 reserves the keyword _Imaginary for use as a type-specifier in conjunction with an experimental/optional feature called a "pure imaginary" type, specified in informative Annex G. The overall intent of the feature is to regularize the effects of "maximal IEEE" behaviors on operations involving complex types. Annex F of C99 specifies a set of "maximal IEEE" behaviors that give optional aspects of the IEEE standard a binding in C semantics, and provides that a C implementation should predefine the macro __STDC_IEC_559__ with a value of 1 if it conforms to all of the specifications in Annex F (note that IEC 60559:1989, IEC 559:1989, IEEE 754-1985, and IEEE 854-1987 are all essentially equivalent for an implementation that uses binary radix). Compaq C does not predefine __STDC_IEC_559__, and does not implement the _Imaginary type that addresses the issues of using __STDC_IEC_559__ features on the complex data types. In Compaq C, use of the _Imaginary keyword produces a warning, which is resolved by treating it as an ordinary identifier.

5.6 Enhancements in V6.2

This release primarily contains a number of new language features from the in-process revision to the C standard, C9X (expected to be C99), and from the gcc compiler (to aid compatibility with source code from Linux systems). It also has run-time performance enhancements (including tuning for the EV6 processor and per-function optimization controls) and diagnostic message improvements, as well as bug fixes and miscellaneous improvements.

The following specific enhancements were made:

  • preprocessor expressions evaluated in 64 bits (C9X)
    Arithmetic expressions evaluated within the preprocessor (i.e the expression in a #if directive) are now evaluated in the type long long (64 bits) instead of long (32 bits).
  • unreachcode message no longer enabled by default
    The unreachcode message, which detects unreachable code is no longer enabled by default. If you wish the compiler to output this message, it must be enabled using either a command line qualifier or a #pragma message directive.
  • diagnostic for unbalanced pragma state save/restore
    The compiler now issues a diagnostic when a #pragma stack is not empty at the end of a compilation (i.e. when the program issues a #pragma <pragma-name> save directive without ever issuing a corresponding #pragma <pragma-name> restore
  • additional diagnostics to help locate unmatched braces
    When a closing brace is omitted, the parser error is generally reported against a location far from the point of the actual coding error. Additional diagnostics now attempt to find which opening brace was not matched, based on heuristic observation of the indentation style used in the rest of the source code. In testing, these messages have proved quite accurate, but if the source code is very inconsistent in this style, or uses an unusual style, the messages may not be very effective. We would appreciate feedback on this feature, particularly testcases where the diagnostic misidentified which brace was unmatched.
  • tuning for the EV6 processor and correction to new builtin functions.
    The V6.0 compiler's support for the EV6 processor was not well-tuned and sometimes its EV56 tuning greatly outperforms its EV6 tuning when running on an EV6 processor. This has been addressed (although some programs may still run better with EV56 tuning, this should happen much less often and with a much smaller margin of difference). Also, the builtin functions _popcnt, _poppar, _leadz, and _trailz were corrected to avoid generating new EV67 instructions on EV6 machines, and their return types were changed from unsigned __int64 to __int64. The latter change represents an ease-of-use improvement (unsigned operands can cause surprising results for arithmetic expressions) and corrects an unintended incompatibility with Tru64 UNIX.
  • initial support for EV67 processor
    EV67 is now accepted as a keyword for the /arch and /opt=tune qualifiers. This enables generation of the bit-counting instructions for the _popcnt, _poppar, _leadz, and _trailz builtin functions.
  • per-function optimization control: #pragma optimize
    #pragma optimize sets the optimization characteristics of function definitions that follow the directive. It allows options to control optimization that are normally set on the command line for the entire compilation to be specified in the source file individually for specific functions. Note that while the controls have effects similar to corresponding command line controls, the final generated code will be somewhat different. In particular, the optimization level controls specified by the pragma do not affect the final instruction-level optimizations and scheduling - those phases of optimization are controlled only by the command-line optimization level.


     
      Syntax: 
     
        #pragma optimize <options> 
     
        Where <options> is one of: 
            save, restore, <settings> 
     
        and <settings> is any combination of: 
            <level settings> 
            <unroll settings> 
            <ansi-alias settings> 
            <intrinsic settings> 
     
        <level settings> sets optimization level, of the form: 
            level=n 
        where n is from 0 to 5. 
     
        <unroll settings> controls loop unrolling, of the form: 
            unroll=n 
        where n is a non-negative integer. 
     
        <ansi-alias settings> controls ansi-alias assumptions: 
            ansi_alias=on   or   ansi_alias=off 
     
        <intrinsic settings> controls recognition of intrinsics: 
            intrinsics=on   or   intrinsics=off 
     
        Whitespace is optional between the setting clauses and 
        before and after the "=" in each clause.  The pragma is 
        not subject to macro replacement.  
     
        An example would be: 
     
            #pragma optimize level=5 unroll=6 
     
        If the level=0 clause is present, it must be the only 
        clause present. 
     
        This directive must appear at file scope - outside any 
        function body. 
     
    

    Semantics:
    1. The save and restore options save and restore the current optimization state (level, unroll count, ansi-alias setting, and intrinsic setting). This is similar to the other environment controls (message, member_alignment...).
    2. #pragma environment save and restore operations include the optimization state.
    3. #pragma environment command_line resets the optimization state to that specified on the command line.
    4. If the pragma does not specify a setting for one of the optimization states, that state will remain unchanged.
    5. When a function definition is encountered, it is compiled using the optimization settings current at that point in the source.
    6. When a function is compiled under level=0, the compiler will not inline that function. In general, when functions are inlined, the inlined code is optimized using the optimization controls in effect at the call site instead of using the optimization controls specified for the function being inlined.
    7. When the VMS command line specifies /NOOPT (or /OPTIMIZE=LEVEL=0), the #pragma has no effect (except that its arguments are still validated).
  • new keywords for /accept qualifier
    New keywords for the /accept command line qualifier:
    • [no]c99_keywords
      Controls whether or not the new keywords being introduced in the C standard that are in the C89 namespace for user identifiers (inline and restrict) are accepted without double leading underscores.
    • [no]gccinline
      The gcc compiler implements an inline function qualifier for functions with external linkage that gives similar capabilites to the C9X feature described below, but the details of usage are somewhat different (basically the combination of extern and inline keywords makes an inline definition, instead of the exclusive use of the inline keyword without the extern keyword). This option controls which variation of the feature is implemented.
  • extern inline functions (C9X and gcc)
    A new keyword, inline , has been introduced which can be used as a declaration specifier in the declaration of a function. With static functions, this has the same effect as applying #pragma inline to the function. When the specifier is applied to a function with external linkage, besides suggesting to the compiler that calls within that translation unit be inlined, there are additional rules that allow calls to the function also to be inlined in other translation units or else called as an external function at the compiler's discretion:
    • If the inline keyword is used on a function declaration with external linkage, then the function must also be defined in the same translation unit.
    • If all of the file scope declarations of the function use the inline keyword but do not use the extern keyword, then the definition in that translation unit is called an inline definition, and no externally-callable definition is produced by that compilation unit. Otherwise, the compilation unit does produce an externally-callable definition.
    • An inline definition must not contain a definition of a modifiable object with static storage duration, and it must not refer to an identifier with internal linkage. These restrictions do not apply to the externally-callable definition.
    • As usual, at most one compilation unit in an entire program can supply an externally-callable definition of a given function.
    • Any call to a function with external linkage may be translated as a call to an external function, regardless of the presence of the inline qualifier. It follows from this and the previous point that any function with external linkage that is called must have exactly one externally-callable definition among all the compilation units of an entire program.
    • The address of an inline function with external linkage is always computed as the address of the unique externally-callable definition, never the address of an inline definition.
    • A call to an inline function made through a pointer to the externally-callable definition may still be inlined, or translated as a call to an inline definition, if the compiler can determine the name of the function whose address was stored in the pointer.
  • intermixed declarations and code, "for" loop declarations (C9X and gcc)
    The C++ language has always allowed these, and they are now being added to C. The rules are the same as for C++. Within a compound statement, statements and declarations may be freely interspersed. This allows declarations to be placed nearer to their point of first use without introducing additional nested compound statements.
    And in the for statement, the first clause may be a declaration whose scope includes the remaining clauses of the for header and the entire loop body. This is normally used to declare and initialize a local loop control variable, e.g.


     
     
        for (int i=0; i<10; i++) 
            printf("%d\n", i); 
     
     
    
  • __func__ predeclared identifier (C9X and gcc)
    Anywhere within the body of a function definition, code can assume that there is visible an identifier named __func__ that is declared as a static array of char initialized with the spelling of the function's name. E.g a function defined as


     
    void foo(void) {printf("%s\n", __func__);} 
     
    

    will print "foo".
  • compound literals (C9X and gcc)
    A compound literal is a new form of expression that constructs the value of an object, including objects of array, struct, or union type. In C89, passing a struct value to a function typically involves declaring a named object of the type, initializing its members, and passing that object to the function. A compound literal is an unnamed object specified by syntax consisting of a parenthesized type name (i.e. the same syntax as a cast operator) followed by a brace-enclosed list of initializers. Note that the initializer list can use the recently-introduced designator syntax.
    E.g. to construct an array of 1000 ints that are all zero except for array element 5, which is to have a value of 7, you can write: (int [1000]){[5] = 7}.
    A compound literal object is an lvalue. The object it designates has static storage duration if it occurs outside of all function definitions, and otherwise has automatic storage duration associated with the nearest enclosing block.
  • comment introducers optionally detected within comments, to help find unterminated comments
    The new message "nestedcomment" can be enabled to report occurrences of "/*" inside of a comment introduced by "/*". This often indicates that a terminating "*/" was omitted, although certain coding practices may also produce many occurrences that are harmless. The message is also enabled by enabling the "level4", "unused", or "questcode" groups.
  • __align synonym for _align (ANSI namespace)
    The long-supported _align storage class modifier is in the namespace reserved for users' identifiers in some contexts under the C standard, and so it could not be recognized as a keyword in strict ANSI mode (/standard=ansi89). An alternate spelling with two leading underscores (putting it in the namespace reserved to the C implementation) is now recognized in all modes so that the feature can be used when compiling in strict ANSI mode.
  • __typeof__ unary operator (gcc)
    The gcc compiler provides an operator named "__typeof__" that can be used much like the standard C operator "sizeof", except that instead of producing a value (the size of an expression or type) it produces a type (the type of the expression or type that is its single operand). It can be convenient to use in macros for generating declarations or casts that use the same type as some expression or typename supplied as an argument to the macro.
  • pointer arithmetic on void and function pointers (gcc)
    Pointer arithmetic on void* pointers or pointers to functions formerly produced hard errors. The gcc compiler allows this, treating both as if they were char* pointers. This behavior has been adopted, with an appropriate warning instead of an error.
  • string initializers optionally enclosed in parentheses (gcc)
    In standard C, a string literal ordinarily has type char *. A special case is made when a string literal is the initializer for an array of char, in which case it is essentially treated as an array object that provides the values (and, in the case of an incomplete array, the size) of the array of char being initialized.
    Also in standard C, a string literal enclosed in parentheses is not itself a string literal, and so this special case would not apply - instead the parenthesized literal would be treated as a single pointer of type char *, which is not a valid initializer for an object of type array of char.
    The gcc compiler allows a parenthesized string literal to initialize a char array, and the construct commonly appears in Linux source code. So that behavior has been adopted, with an appropriate warning.
  • difference of addresses in same object are constants (gcc)
    If the & operator is used to obtain the addresses of two lvalues within the same object, and the lvalues are specified with integral constant expressions, then the result depends only on the layout of the object, and for practical purposes can be computed at compile time much like the integral constant expressions that are required to be produced by sizeof and offsetof.
    E.g. for any array "a" of int, the value of &a[4] - &a[3] must be sizeof(int), and sizeof(int) is an integral constant expression. But the C standard's specification of expressions that must be treated by the compiler as integral constant expressions does not include use of the & operator, and so &a[4] - &a[3] is not required to be treated as such, and Compaq C has not previously done so. But the C standard also explicitly recognizes that implementations may treat additional forms of expressions as constant expressions, and gcc and other compilers do treat these cases as integral constant expressions. Now Compaq C does as well.
  • allow #pragma use_linkage to take typedef names as well as functions
    #pragma use_linkage directive has been extended so that it can take either a typedef name or a function name. If the typedef name is a function type, then functions or pointers to functions declared with that type will have the specified linkage. This allows programmers to invoke functions that have a special linkage using a pointer to a function.

5.7 Enhancements in V6.0

  • New command line qualifier /[NO]PROTOTYPES:


     
        /[NO]PROTOTYPES=(FILE=<filename>, 
                        [NO]IDENTIFIERS, 
                        [NO]STATIC_FUNCTIONS) 
     
        default is /[NO]PROTOTYPES 
     
    Syntax Description: 
     
        /[NO]PROTOTYPES 
            Creates an output file containing function prototypes 
            for all global functions defined in the module which 
            is being compiled. 
     
        keywords: 
     
          IDENTIFIERS 
                negatable optional parameter, which indicates that 
            identififer names are to be included in the prototype 
            declarations that appear in the output file.  The 
            default is NOIDENTIFIERS 
     
          STATIC_FUNCTIONS 
            negatable optional parameter, which indicates that 
            prototypes for static function definitions are to be 
            included in the output file.  The default is 
            NOSTATIC_FUNCTIONS 
     
          FILE=<filename> 
            an optional parameter specifying the output file name. 
            When not specified the output file name will be 
            have the same defaults as listing file, except that 
            the .CH file extension is used instead of the .LIS 
            extension. 
     
    
  • New command line qualifier /ASSUME=[NO]WEAK_VOLATILE. Specifying /ASSUME=WEAK_VOLATILE tells the compiler to generate code for assignments to objects that are specified as volatile and smaller than 32 bits without the load-locked/store-conditional sequences that in general are required to assure volatile data integrity. This option is intended for use in special hardware access situations, and should not generally be used.
  • New command line qualifier, /SHOW=MESSAGES . This qualifier adds a new section to the listing file showing all of the compiler's diagnostic messages that are enabled at the start of the compilation, after the command line has been processed. The listing shows the message identifer, the severity, and the parameterized text of each enabled message, reflecting the effects of the /standard and /warnings command line qualifiers (except that severity-based suppression, /warnings=noinformationals or /nowarnings, is not reflected). The /warnings=verbose qualifier causes this listing to be expanded with the "Description" and "User Action" text following the text for each enabled message.
  • New command line qualifier, /CHECK=BOUNDS . This qualifier causes the compiler to generate code to check the bounds of array-indexing expressions at runtime, and raise an exception (%SYSTEM-F-SUBRNG, arithmetic trap, subscript out of range) if the index is out of bounds. Note that the C language defines the subscript expression a[i] to be equivalent to *(a+i), relying on the implicit conversion of an array name to a pointer to the first element of an array, and on the fact that adding an integer to a pointer involves "scaling" the index by the size of the pointed-to object. So array syntax can be used either with pointers or with the names of arrays. Array bounds are only checked when an element is accessed using a declared array name (using either array notation or pointer +/- integer notation). In particular, the check is made at the point that the compiler processes an add or subtract of an array name and an integer - the result of that operation is a pointer, and so subsequent operations are not included in the checking code. Also note that the C language considers computation of the address one past the end of an array to be fully portable. Therefore, expressions that appear to compute an address allow an extra element at the end. It is only when an array name is used directly with array subscript notation that the exact upper bound is checked. E.g.


     
    { 
        int a[5]; // elements are 0..4, but you 
                  // can take the address of a[5] 
        int *pa, i=6, j=-6; 
        pa = a + i;          // trap, &a[6] 
        pa = a + i + j;      // trap, &a[6] - 6 
        pa = a + (i + j);    // no trap, &a[0] 
        pa = a + (i - 1);    // no trap, &a[5] 
         j = a[i - 1];       // trap, a[5] 
         j = *(a + (i - 1)); // no trap, looks like &a[5] 
    } 
     
    
  • New informationals to report apparently unnecessary #include files and CDD records. The most useful of these, UNUSEDTOP, reports only headers explicitly #included at the top level in the compilation unit that did not provide anything used by the rest of the compilation. This message is enabled at level4. Other diagnostics to report on the effects of #includes nested within other headers, and on CDD records, are enabled at level5. All of these messages can be enabled by the message group UNUSED. Unlike any other messages, these messages must be enabled on the command line in order to be effective. The processing that analyzes the dependencies on included files is signficant, and it must be started before processing of the input files begins. Any #pragma message directives within the source have no effect on these messages, their state is determined only by processing the command line.
  • Variable length arrays from the C9X review draft have been implemented. This feature permits array objects with auto storage class, and array typedefs declared at block scope, to have bounds that are runtime-computed expressions. It also permits the declaration and definition of functions whose parameters are arrays dimensioned by other parameters (similar to Fortran assumed-shape arrays). The following example illustrates both uses. Note that the definition of function sub() uses prototype syntax and that the dimension parameters precede the array parameter that uses them. In order to define a function with the dimension parameters following the array parameter that uses them, it is necessary to write the function definition using K&R syntax (since that syntax allows the declarations of the types of the parameters to be written in a different order from the parameters themselves). K&R function definitions should generally be avoided.


     
      #include <stdio.h> 
      #include <stdlib.h> 
     
      void sub(int, int, int[*][*]); 
     
      int main(int argc, char **argv) 
      { 
          if (argc != 3) { 
              printf("Specify two array bound arguments.\n"); 
              exit(EXIT_FAILURE); 
          } 
          { 
              int dim1 = atoi(argv[1]); 
              int dim2 = atoi(argv[2]); 
              int a[dim1][dim2]; 
              int i, j, k = 0; 
              for (i = 0; i < dim1; i++) { 
                  for (j = 0; j < dim2; j++) { 
                      a[i][j] = k++; 
                  } 
              } 
              printf("dim1 = %d, dim2 = %d.", 
                     sizeof(a)/sizeof(a[0]), 
                     sizeof(a[0])/sizeof(int)); 
     
              sub(dim1, dim2, a); 
              sub(dim2, dim1, a); 
          } 
          exit(EXIT_SUCCESS); 
      } 
     
      void sub(int sub1, int sub2, int suba[sub1][sub2]) 
      { 
          int i, j, k = 0; 
          printf("\nIn sub, sub1 = %d, sub2 = %d.", 
                            sub1,      sub2); 
          for (i = 0; i < sub1; i++) { 
              printf("\n"); 
              for (j = 0; j < sub2; j++) { 
                  printf("%4d", suba[i][j]); 
              } 
          } 
      } 
     
    

    Finally, note that variable length arrays can often be used in place of the non-standard alloca() [__ALLOCA()] intrinsic, an important difference being that the storage allocated by __ALLOCA is not freed until return from the function, while the storage allocated for a variable length array is freed on exit from the block in which it is allocated. If __ALLOCA is called within the scope of a variable length array declaration (including within a block nested within the block containing a variable length array declaration), then the storage allocated by that call to __ALLOCA is freed at the same time that the storage for the variable length array is freed (i.e. at block exit rather than function return). The compiler issues a warning in such cases.

5.8 Enhancements in V5.7

This release contains a number of new features aimed primarily at ease of use and programmer productivity, as well as performance and bug fix improvements.

  • New command line qualifier, /OPTIMIZE=INTRINSICS . In V5.6, the special treatment of various standard runtime library functions was accomplished solely by explicit source code in the standard header files. E.g. in <string.h> there is: #define memcpy(__x, __y, __z) __MEMCPY(__x, __y, __z). As a result, the compiler would not give special treatment to calls to memcpy unless the compilation #included the standard header. Similarly, the compiler did not do compile-time analysis of printf format strings unless <stdio.h> was #included and the macro _INTRINSICS was defined. Under this new option, extern functions whose names and call signatures match those of standard library functions can be recognized automatically as special (intrinsic) even if the corresponding header file is not included. In addition, many more functions can be handled as intrinsics than were previously available through the header files. The online help for this qualifier contains the list of functions currently recognized. The default is /OPTIMIZE=INTRINSICS .
  • New command line qualifier /ASSUME=NOMATH_ERRNO . The C standard requires that calls to certain library functions in <math.h> communicate error information using errno. Since this behavior effectively means that calls to such functions must be considered to have side-effects, the calls cannot be optimized. This option asserts to the compiler that the program does not depend on the setting of errno by those functions, allowing the compiler to optimize calls to them. In practice, most production-quality C programs that perform substantial floating point computations do not rely on the setting of errno by math library functions. But because the setting of errno by math functions is a traditional behavior that is also required by the standard, and the compiler cannot reliably determine whether or not the program actually depends on it, the compiler must refrain from optimizing these math function calls unless the user explicitly allows it by specifying this option. The online help for /OPTIMIZE=INTRINSICS lists the functions affected.
  • New command line qualifier /ASSUME=WHOLE_PROGRAM . This qualifier asserts to the compiler that it is compiling the entire program at one time, except for "well-behaved" library routines. This is normally useful only in conjunction with /PLUS_LIST_OPTIMIZE . A well-behaved library routine is one that does not use external linkage to read or write any global variables that are visible to the compilation, and does not use external linkage to access any function defined in the compilation. It is a slightly stronger assertion than /ASSUME=NOPOINTERS_TO_GLOBALS .
  • New command line qualifier EXACT_CDD_OFFSETS. This qualifier tells the compiler to use the exact offsets as specified by #pragma dictionary records, regardless of the current state of alignment controls. By default, the offsets specified by CDD may be rounded up, subject to the alignment controls in effect at the point of the #pragma .
  • New command line qualifier /CHECK=POINTER_SIZE=INTEGER_CAST . Generates a runtime check to verify that no bits are lost whenever a 64-bit pointer is cast to a 32-bit integer.
  • New command line qualifier /ASSUME=NOCLEAN_PARAMETERS . This qualifier tells the compiler that functions defined in this compilation may be called from a separate compilation and passed improperly-prepared arguments. In particular, functions defined to take 32-bit integer or pointer arguments will have additional code generated to sign-extend the upper 32 bits of each such argument. Note that the Calling Standard for Alpha requires that 32-bit values must be passed in 64-bit sign-extended form, even when the argument is of an unsigned type. But type mismatches across separate compilation units can cause this requirement to be violated, and use of this option can help detect/correct the problem in order to aid the developer. Ordinarily, this option should not be necessary and is not recommended for production code.
  • New command line qualifier /OPTIMIZE=PIPELINE . At optimization levels of 2 or higher, this qualifier enables an optimization called "software pipelining", in which certain loops may be reordered to start some of the work of one iteration in an earlier iteration, and in some cases perform data prefetching to reduce the impact of cache misses. This optimization is included by default at level 5.
  • Enhanced diagnostic message controls. The /WARNINGS command line qualifier and its matching #pragma message have had a number of new features added in an upwardly-compatible way. Refer to the online help for /WARNINGS for specific usage information. Features include:
    • Specify whether a message is issued only once per compilation, or at each occurrence.
    • Reduce the severity of any message that has a default severity of informational or warning, or increase the severity of any message. Reducing a warning to an informational can allow generation of a "warning-free object module", without suppressing the diagnostic altogether. Increasing the severity of an informational or warning to an error can help enforce programming practices by causing specific diagnostics to "break" a build.
    • Control optional messages using a single numeric "importance level". The "check" group of messages basically allowed enabling a large number of additional messages, some useful, some not very useful in many cases. Messages have now been grouped into 5 importance levels, named level1-level6. The default is level3. The "check" group is now treated as a synonym for level5. The "all" group is treated as a synonym for level6. The level1 and level2 groups correspond to "quiet" and slightly more "noisy" versions of Digital UNIX compilers, respectively. Enabling a level enables optional messages at that level and all lower levels. Disabling a level disables optional messages at that level and all higher levels.
    • Control optional messages using functional groups. The previous functional groups (c_to_cxx, check, portable, all) have been retained, and a number of new groups have been added. Many of the names for the new functional groups correspond to groups recognized by the "lint" utility on DIGITAL UNIX: ALIGNMENT, DEFUNCT, NOANSI, OBSOLESCENT, OVERFLOW, PERFORMANCE, PREPROCESSOR, QUESTCODE, RETURNCHECKS, UNINIT, UNUSED, CDD.
    • /WARNINGS=VERBOSE adds explanatory help text following each diagnostic message output.

    Besides the new features, the entire set of compiler messages was reviewed and updated. As a result, the exact set of messages reported by a default compilation is somehwat different. Overall, the default level3 setting is slightly quieter, particularly because the default mode of relaxed_ansi does not report uses of language extensions. Also, the severity of many warning messages has been reduced to informational. Finally, the Messages subtopic for CC now contains useful additional information about each message.
  • New command line qualifier /SHOW=SYMBOLS . This will add a symbol table map to the listing (if a listing is requested). This is similar, but not identical, to the output from the VAX C compiler.
  • New command line qualifier /SHOW=BRIEF . This qualifier is similar to the new qualifier /SHOW=SYMBOLS , except that unreferenced symbols declared in header files are omitted.
  • New command line qualifier /CROSS_REFERENCE , or equivalently /SHOW=CROSS_REFERENCE . This qualifier adds a list of line numbers at which each listed symbol is referenced (if a listing is requested). If the /SHOW qualifier is omitted, this qualifier causes the /SHOW=BRIEF symbols to be listed. When appropriate, the line number designating a reference to a symbol is annotated with a suffix indicating the way in which the symbol was used on that line, as follows:
    • = Assigned or initialized.
    • & Address taken.
    • () Function called.
    • * Simple dereference.
    • -> Member dereference.
    • . Member selection (no indirection).
    • [] Subscripted (i.e. using [] syntax).
    • b Invoked as a builtin function.
  • New command line qualifier /ACCEPT=[NO]feature . This qualifier tells the compiler to accept (or reject) particular language features, regardless of the setting of the /STANDARD qualifier. There are two features that can be controlled in this way:
    • VAXC_KEYWORDS . Specifying this feature tells the compiler to recognize and process the following identifiers as keywords: _align, globaldef, globalref, globalvalue, noshare, readonly, variant_struct, variant_union. Specifying NOVAXC_KEYWORDS tells the compiler to treat these as ordinary identifiers. The default is to recognize these as keywords in all language modes other than strict ANSI and common modes.
    • RESTRICT_KEYWORD . Specifying this feature tells the compiler to recognize and process the C9X keyword restrict as a type qualifier keyword. By default, in current language modes only the reserved-namespace spelling __restrict is treated as a keyword.
  • New command line qualifier /NAMES=SHORTENED . External symbol names longer than 31 characters are, by default, truncated to 31 characters by the compiler in order to conform to the linker limit, as they always have been. This new option instructs the compiler to shorten the name without losing all information about the characters that were removed. The shortened name contains a CRC encoding of the characters removed, similar to way that the C++ compiler treats its mangled names that very often exceeed 31 characters. This allows programs containing long external names that are not unique within the first 31 characters to be linked successfully. Naturally, if a program contains external names longer than 31 characters, all of its modules must be compiled with the same setting of this qualifier in order to link successfully. The default is /NAMES=TRUNCATED .
  • New command line qualifier /REPOSITORY=dirspec . This qualifier is only useful in conjunction with /NAMES=SHORTENED , and when the default directory specification of [.CXX_REPOSITORY] is not acceptable. When the compiler shortens a name under the /NAMES=SHORTENED option, it also writes a mapping from the shortened name to the original full-length name in the repository. The CXXDEMANGLE utility, which now also ships with the C compiler, can be used to find the original name corresponding to a shortened name. That utility also assumes that the shortened name repository is located in [.CXX_REPOSITORY] unless a different directory is explicitly specified. See the help for CXXDEMANGLE . An option to perform compatible shortening on long names with extern "C" linkage is planned for a future release of C++. Note that a shortened C name is formed using a convention that will never match a C++ "mangled" name, so a single repository can be used by all C and C++ compilations.

5.9 Enhancements in V5.6

This is primarily a maintenance release focused on bug fixes, performance, usability and message improvements, and providing V7.1 runtime library features on prior versions of VMS.

  • Optimizer for Alpha now exploits the __restrict qualifier in limited ways. Future releases will expand this kind of optimization.
  • Optional compile-time diagnostics and optimizations for certain kinds of format strings passed to the printf family of library functions.
    If a preprocessor macro named "_INTRINSICS" is defined prior to inclusion of the V5.6 header file stdio.h, the compiler will perform compile-time analysis of format strings and arguments passed to printf, fprintf, and sprintf when possible. When the format string passed to one of these functions is an explicit compile-time-known string, this feature permits the compiler to diagnose mismatches in number and type between the %-specifiers in the format string and the arguments to be formatted. Most such format strings will be converted to a more efficient run-time encoding handled by new library routines. In addition, a number of special cases are recognized which will cause the compiler either to generate calls directly to lower-level library routines instead of printf, or to generate inline code, avoiding the need to do any format decoding at runtime. For example, a format such as "%s" passed to fprintf() can be converted to a call to fputs(). When passed to sprintf, it might be converted either to a call to strcpy or to inline code to copy characters into the buffer. In versions of OpenVMS through V7.1, the runtime support for this feature is provided only through object modules placed in SYS$LIBRARY:STARLET.OLB by this kit.
  • Command line qualifiers /ARCHITECTURE= and /OPTIMIZE=TUNE= documented in online help, allow the compiler to exploit more fully features of newer Alpha chips including byte/word memory access instructions.
  • Message group C_TO_CXX. This message group contains an optional set of diagnostics that report the use of a number of C language constructs that are not compatible with, or have a slightly different meaning in, the C++ language. This group may be enabled explicitly either on the command line (/WARN=ENABLE=C_TO_CXX) or by #pragma message enable (c_to_cxx).
  • New runtime check, /CHECK=POINTER_SIZE=INTEGER_CAST. This causes the compiler to generate code to check at runtime that casts from 64-bit pointer to 32-bit integer do not overflow. The expected behavior of casts to integer types is to truncate the value silently. But in porting 32-bit code to exploit 64-bit pointers, such casts can occur unintentionally and produce runtime failures that are otherwise very difficult to analyze.
  • New diagnostics to detect simple expressions with side effects that are undefined in ANSI C. The C standard formalized defacto rules about side effects in terms of sequence points. An expression that modifies the same object more than once, or that modifies an object and fetches its value for a purpose other than computing the modified value, has undefined behavior unless there is an intervening sequence point. The compiler now warns about such expressions (only for objects that are simple declared variables).
  • Source listings now include statement level nesting. The annotation at the left margin of the source listing now includes the statement nesting level in effect at the end of that source line. The statement nesting level appears as a simple integer before the listing line number. The block of a function definition is level 1. Outside of function definitions, this field is blank.

5.10 Enhancements in V5.5

This is primarily a maintenance release focused on bug fixes, with very limited new functionality.

  • New command line qualifier /ASSUME=NOPOINTERS_TO_GLOBALS .
    This qualifier tells the compiler it is safe to assume that global variables have not had their addresses taken in a separate compilation. By default, the compiler assumes that global variables may have had their addresses taken in separately compiled modules, and that in general any pointer dereference may be accessing the same memory as any global variable. This is often a significant barrier to optimization. The /ANSI_ALIAS command line qualifier allows some resolution based on data type, but this new qualifier provides significant additional resolution and improved optimization in many cases. Note that this qualifier does not tell the compiler that the compilation never uses pointers to access global variables (which is seldom true of real C programs). Instead, it tells the compiler that any global variable accessed through a pointer in the compilation must have had its address taken within that compilation. In combination with /plus_list_optimize, several source modules can be treated as a single compilation for the purpose of this analysis. Since runtime libraries such as the CRTL do not take the addresses of global variables defined in user programs, it is often possible to combine source modules into a single compilation that allows this qualifier to be used effectively.
  • New type qualifier " __restrict "
    The ongoing work to revise the ANSI C language standard will likely incorporate a new type qualifier keyword " restrict " (the existing ANSI type qualifiers are " const " and " volatile "). This feature has been present in the Cray C compiler for some time and is also being adopted by other vendors. The type qualifier applies only to pointer types, and its basic purpose is to assert to the compiler that memory accesses made through a pointer declared with this type do not overlap with other memory accesses within the scope of that pointer, permitting additional optimization. In this release, the qualifier (with double leading underscores to avoid violating the ANSI89 namespace) is recognized and its correct compile-time usage is verified, but it does not yet trigger additional optimizations.
  • Initial macros shown in listing file
    At the end of the listing file there is now a section containing a list of all macros in effect at the start of the compilation, along with their values. This includes both those predefined by the compiler (except for ANSI-mandated macros that cannot be undefined or redfined) and the result of applying all /DEFINE and /UNDEFINE qualifiers.

5.11 Enhancements in V5.3

  • New qualifier keyword value /STANDARD=MS.