A.1 Features Affecting the Compiler

This section describes DEC C compiler features. (Section A.2 describes features that affect the DEC C run-time library and include files.)

A.1.1 DEC C Qualifiers

Qualifiers new to DEC C:

A.1.2 Comment Processing

VAX C treats a comment in a macro definition as if the comment were replaced with no characters. This allows comments to paste tokens together, as in the following example:

#define PASTE(X) X/*  */1
int PASTE(VAR);

This example declares the variable VAR1. ANSI C requires that comments be treated as if they were replaced by a single space. In DEC C, therefore, comments cannot be used to concatenate tokens when /STANDARD=ANSI89 or /STANDARD=RELAXED_ANSI89 is specified. (The new operator ## is provided to allow token concatenation in macros.)

DEC C for OpenVMS Systems continues to replace comments with no characters when /STANDARD=VAXC or /STANDARD=COMMON is specified; and /WARN=ENABLE=CHECK provides a diagnostic to flag comments that are used to concatenate tokens.

For /STANDARD=COMMON and /STANDARD=RELAXED_ANSI89, C++ style comments (//) are supported.

A.1.3 String Literal Concatenation

DEC C introduces a new ANSI-compliant feature that allows convenient continuation of string literals. If string literals are separated only by white space, the string literals are concatenated to form one string literal. For example:

fputs("This is really "
   "one string literal", stderr);

String literal concatenation works for both normal string literals and wide string literals.

A.1.4 Recursive main() Function

In VAX C, main, or any function using the VAX C main_program option, is not recursively reentrant.

As required by ANSI C, the main function in DEC C can now be called recursively.

A.1.5 Trigraph Sequences

ANSI C defines an additional representation of some of the special characters in the C language source abstract character set. These additional representations are sequences of three characters called trigraphs. Table A-1 lists the trigraphs and the character each is mapped to.

Table A-1 Trigraphs

Trigraph  Replacement 
??= 
??( 
??/ 
??) 
??' 
??< 
??! 
??> 
??-  

Conceptually, every trigraph is removed from the file and its replacement is substituted. Each ? that does not begin one of the trigraphs is not changed. Trigraph processing occurs before tokenization takes place. Thus, even trigraphs in string constants have their replacements substituted.

Trigraph support has the potential to change the meaning of existing C code that unintentionally contains a trigraph in a string literal. However, since such conflicts will be quite rare, there is no facility for disabling trigraph support.

Trigraph support is available in strict and relaxed ANSI C mode.

A.1.6 Alert Escape Sequence

As specified by ANSI C, DEC C defines a new escape sequence for the alert character. The escape sequence \a represents the ASCII BEL (Ctrl/G) character.

A.1.7 Hexadecimal Escape Sequence

VAX C limits hexadecimal escape sequences to at most 3 hex digits, but ANSI C allows an unlimited number of digits. DEC C removes the limit imposed by VAX C.

This can cause some programs to behave differently. The string "\x0012" is currently interpreted by VAX C as a string with two characters in it: a Ctrl/A followed by the character "2". Under ANSI C rules, the string consists of a single character whose character code is hexadecimal 12 (Ctrl/R). However, this problem is unlikely to occur in practice.

A.1.8 Invalid Escape Sequences

DEC C issues a warning message if it encounters an invalid escape sequence. VAX C did not diagnose such usage.

A.1.9 $ in Macro Names

The dollar sign ($) is not an element of the minimum basic character set allowed by the ANSI C standard. By a systemwide convention, the dollar sign identifies Digital reserved identifiers. DEC C for OpenVMS Systems supplies header files containing many macros with dollar signs in their names, and the VAX C compiler predefines some macros with dollar signs in their names. In strict ANSI C mode, such macros trigger a warning.

A.1.10 Null Arguments to Macros

In DEC C, null arguments to a macro produce a BUGCHECK. VAX C allowed macro arguments to be null.

A.1.11 ANSI C Name Space Conformance

ANSI C strictly controls the name space of C programs, and prohibits compilers or their standard-specified header files from intruding on the name space reserved for user programs. Specifically, the ANSI C Standard requires that compiler extensions begin with an underscore followed by an uppercase letter or another underscore.

This affects VAX C extensions involving additional keywords and predefined macros. It also affects the freedom of DEC C to add additional macros, variables, and functions to the standard- specified header files, such as <stdio.h>.

The following sections describe how DEC C solves the reserved name space problem for extensions involving keywords, predefined macros, and header file contents.

A.1.11.1 Non-ANSI Keywords

VAX C has several keywords that intrude into the user name space. The DEC C compiler in strict ANSI C mode (/STANDARD=ANSI89) does not recognize keywords that are VAX C-specific extensions to the language. They are recognized instead as identifier names. As a result, programs that use these extensions as keywords cannot be compiled in strict ANSI C mode without eliciting syntax errors.

Similarly, the DEC C compiler in VAX C mode and relaxed ANSI C mode does recognize keywords that are VAX C-specific extensions to the language. Therefore, programs that use these names as identifiers cannot be compiled in VAX C or relaxed ANSI C mode without eliciting syntax errors. In relaxed ANSI C mode, the compiler generates a warning for these keywords. When the /STANDARD=ANSI89 qualifier is used, the compiler strictly follows the ANSI C rules about the name space, and does not recognize the old spellings as keywords.

Table A-2 shows the traditional spelling and the new spelling of the keywords affected, as well as their corresponding ANSI-compliant pragmas.

Table A-2 Non-ANSI Keywords

Keyword  Corresponding ANSI-Compliant Pragma 
globaldef  #pragma extern_model 
globalref  #pragma extern_model 
globalvalue  #pragma extern_model 
noshare  #pragma extern_model 
readonly  #pragma extern_ model 

A.1.11.2 Non-ANSI Predefined Macros

Alternate spellings that follow ANSI C rules are added to DEC C for all VAX C predefined macros. For compatibility, both the old spellings of the predefined macros and the new spellings are recognized by the compiler. However, when the /STANDARD=ANSI89 qualifier is used, the compiler strictly follows the ANSI C rules about the name space, and does not recognize the old spellings as predefined macros. You are encouraged to use the new ANSI C conformant spelling of the macros.

Table A-3 shows the traditional spelling and the new spelling of the predefined macros affected

Table A-3 New and Traditional Spellings of Macros

Traditional Spelling  New Spelling 
vax  __vax 
vax11c  __vax11c 
vaxc  __vaxc 
VAX  __VAX 
VAX11C  __VAX11C 
VAXC  __VAXC 
vms  __vms 
VMS  __VMS 
vms_ version  __vms_version 
VMS_ VERSION  __VMS_VERSION 

A.1.11.3 Non-ANSI Identifiers in Standard-Specified Header Files

The ANSI C standard specifies exactly what identifiers in the normal name space are declared by the standard header files. A compiler is not free to declare additional identifiers in a header file unless the identifiers follow defined rules (the identifier must begin with an underscore followed by an uppercase letter or another underscore).

When running the DEC C compiler on OpenVMS systems in strict ANSI C mode (/STANDARD=ANSI89), versions of the standard header files are included that hide many identifiers that do not follow the rules. The <stdio.h> header file, for example, hides the definition of the macro TRUE. The compiler accomplishes this by predefining the macro __HIDE_FORBIDDEN_NAMES in strict ANSI C mode.

You can use the command-line qualifier /UNDEFINE="__HIDE_FORBIDDEN_ NAMES" to prevent the compiler from predefining this macro, thus including macro definitions of the forbidden names.

The header files are modified to only define additional VAX C names if __HIDE_FORBIDDEN_NAMES is undefined. For example, <stdio.h> might contain the following:

#ifndef __HIDE_FORBIDDEN_NAMES
#define TRUE    1
#endif

A.1.12 DEC C Predefined Macros

DEC C for OpenVMS Systems supports the following new system- identification macros:


__DECC
__alpha
__ALPHA
__Alpha_AXP
__32BITS
__mia
__STDC__

A.1.13 DEC C Types

The following sections describe changes to the data types supported by DEC C.

A.1.13.1 signed Reserved Word

DEC C supports the new reserved word signed to complement unsigned. The signed keyword may be used with the char, short, int, and long keywords to specify the types signed char, signed short, signed int, and signed long. (These types are already supported by VAX C.) The signed keyword can also be used when declaring bit fields to specify explicitly that the bit field is signed.

ANSI C specifies that signed short, signed int, and signed long are the same types as short, int, and long, respectively. However, signed char is not the same type as char, even though DEC C uses the same representation for both of them. This does not affect normal mixing of the two types, but it does mean that in DEC C a pointer to signed char is not compatible with a pointer to char. Note that programs that previously used signed as an identifier will now be in error, even in VAX C mode. The /[NO]UNSIGNED_CHAR qualifier can be used to specify whether char is signed or unsigned.

A.1.13.2 Removal of the long float Type

In VAX C, long float is a synonym for double. Since the ANSI C Standard retires the long float specification, DEC C in strict ANSI C mode diagnoses any use of long float as an error. The long float type is still accepted as a synonym for double in VAX C mode, but it elicits a warning diagnostic to the effect that this is an obsolete usage.

A.1.13.3 Addition of the long double Type

On OpenVMS VAX systems, DEC C maps the ANSI C defined long double type to the G_floating or D_floating format, depending on the /FLOAT (or /[NO]G_FLOAT) qualifier used. (VAX only)

On OpenVMS Alpha systems, the long double type defaults to X_ floating (/L_DOUBLE_SIZE=128). If /L_DOUBLE_SIZE=64 is specified, the long double type is mapped to G_floating, D_floating, or T- floating, depending on the /FLOAT (or /[NO]G_FLOAT) qualifier used. (Alpha only)

The <float.h> header file is modified to define the appropriate values to describe the characteristics of this new data type.

A.1.13.4 Addition of Processor-Specific Integer Data Types

DEC C for OpenVMS Systems supports the following processor-specific integer data types:

These data types are intended for applications that need integer data types of a specific size across platforms that support the data type.

The <ints.h> header file contains typedefs for the signed and unsigned variations of these integer data types. For increased portability, use these typedefs rather than using the built-in data types directly.

Note that the 64-bit integer types are available on OpenVMS Alpha systems but not on OpenVMS VAX systems.

The contents of <ints.h> are:

/*
*  <ints.h> - Definitions for platform-specific integer types)
*
*/

#ifndef #__INTS_LOADED
#define #__INTS_LOADED 1

typedef signed char         int8;
typedef unsigned char       uint8;
typedef signed __int16     int16;
typedef unsigned __int16   uint16;
typedef signed __int32     int32;
typedef unsigned __int32   uint32;

#if defined(__ALPHA)
    typedef signed __int64    int64;
    typedef unsigned __int64  uint64;
#endif

#endif  /* __INTS_LOADED */

A.1.14 The #pragma dictionary (VAX only)

The #pragma dictionary preprocessor directive replaces the #dictionary directive, but the latter is still supported in VAX C mode for compatibility.

A.1.15 Type Compatibility

DEC C for OpenVMS Systems in strict and relaxed ANSI C mode uses different rules than DEC C in VAX C mode to determine if two types are identical:

These rules cause the strict and relaxed ANSI C modes to be much more strict than VAX C mode about type checking.

A.1.16 Composite Types

As required by ANSI C, DEC C merges type information from two declarations of the same object in the same scope. The declarations are required to be type-compatible and the linkage of the declarations must be such that multiple declarations in the same scope are allowed.

The composite type (the merged type) can be formed only from array or function types. Array types can have their array bounds specified, and function types can have their arguments specified.

For example, consider the following two declarations in the same scope:

extern int f(int (*)(), double (*)[3]);
extern int f(int (*)(char *), double (*)[]);

The resulting type for f is:

extern int f(int (*)(char *), double (*)[3]);

The VAX C compiler did not support composite types, although it might have appeared to do so. For example, in VAX C, what appears to be a second declaration of a composite function type, is actually a redeclaration of the function. This might have an effect on the compilation. For example, if the first declaration has ellipses and the second declaration does not, a composite type cannot be formed (not allowed by the ANSI C Standard). However, a redeclaration is done.

Since the composite type feature of the ANSI C standard is important even to those programming in VAX C mode, it is supported in VAX C mode. Therefore, it is possible to encounter declaration combinations that compile under VAX C but not under DEC C in VAX C mode.

A.1.17 Enumerations Have Type int

For type-checking purposes, VAX C previously considered enumeration types to be distinct from each other, and from the integer types, even though enumeration constants and variables have always been usable as ordinary integers. Since the VAX C model of enumerations was overly restrictive even from the strong typing point of view, and since such checking is not common in modern C, DEC C does not treat enumerations as a special type.

A.1.18 long double Constants

As specified by ANSI C, DEC C floating-point constants suffixed by l or L have type long double. (Currently, VAX C gives such constants type double).

A.1.19 Implicit Unsigned Integer Constants

The type of an unsuffixed decimal integer constant is the first type in the following list that can represent its value: int, long int, or unsigned long int.

The type of an unsuffixed octal or hex constant is the first type in the following list that can represent its value: int, unsigned int, long int, or unsigned long int.

A.1.20 Multibyte and Wide Character Support

To meet the needs of non-European languages with large character sets, ANSI C includes a framework to support characters encoded in multiple bytes. This framework is general enough to support character-processing extensions and character-set encodings already used in Asia, and allows for support for the draft proposed ISO Standard 10646, a multiple octet-coded character set that supports dozens of natural languages.

ANSI C supports natural languages with large character sets by recognizing that normal character constants and string literals can be used to represent multibyte characters. A multibyte character is an encoding of variable-length characters where one, two, or more bytes in the string represents a single character in the natural language. The encoding is allowed to support locking shift states that change the encoding of characters for as long as the shift state holds.

Multibyte characters can occur in comments, character constants, and string literals.

Because string manipulation is very difficult when the character size varies from character to character, ANSI C supports a fixed-size representation where each character is stored in the same number of bytes. This representation is called wide character support. DEC C supports a new form of wide character constant and wide string literal.

A.1.20.1 The Wide Character Type

ANSI C requires that wide characters be represented by an integral type, and that there be a typedef named wchar_t for that type in the header <stddef.h>.

DEC C defines wchar_t to be unsigned int. This allows all character sets supported by ISO 10646 to be supported simultaneously.

A.1.20.2 Multibyte Characters in Comments, Character Constants, and String Literals

Full multibyte support requires that the compiler be able to determine whether an individual byte in a multibyte string is a single byte character or part of a multiple byte character. For example, the compiler must be able to distinguish between the single byte quote ending a string literal and a quote that is embedded in a multiple byte character and does not end the string literal.

A.1.20.3 Wide Character Constants

As required by ANSI C, DEC C supports wide character constants. The form of such a constant is the uppercase letter L, followed by a single quote, followed by a multibyte character, followed by a single quote.

The compiler collects the bytes making up the multibyte character into a string, and then calls the DEC C RTL mbtowc function to convert the multibyte character into a wide character. The resulting value has type wchar_t.

A.1.20.4 Wide String Literals

As required by the ANSI C Standard, DEC C supports wide string literals. The form of such a literal is the same as a normal string literal prefixed by the uppercase letter L.

The compiler collects the bytes making up the wide string literal into a string, and then calls the DEC C RTL mbstowcs function to convert the multibyte characters into wide characters. The resulting wide character string literal has type array of wchar_t.

A.1.21 Usual Arithmetic Conversions

In DEC C, the usual arithmetic conversions now support the long double type: if either operand of a binary operator that uses these conversions is long double, then the other operand is converted to long double.

A.1.22 Indexing as a Commutative Operator

As required by the ANSI C Standard, DEC C now defines the array indexing operator, [], as commutative. Thus, if a is an array and i is an integer, both a[i] and i[a] are valid.

A.1.23 Cast Operators

ANSI C specifies that result of the cast operator is not an lvalue. However, VAX C does allow the cast operator to produce an lvalue.

The DEC C compiler in VAX C mode allows the cast operator to produce an lvalue.

A.1.24 Function Calls

The following sections describe changes to function calls.

A.1.24.1 Assignment Compatibility Argument Checking

ANSI C defines a function call made with a prototype in scope as assigning the arguments to the parameters of the function. This means that all of the normal type checking and implied conversions that occur during an assignment take place when calling a function.

VAX C currently follows this model with two exceptions. First, it only performs the required type checking if /STANDARD=PORTABLE is given. Second, the assignment compatibility rules used by VAX C are not as stringent as the rules required by ANSI C. For example, two structs are assignment-compatible in VAX C only if they are the same size.

The DEC C compiler in VAX C mode and common mode is compatible with VAX C in assignment compatibility rules. Other modes follow the stricter ANSI C rules, documented in Section A.1.28 of this guide, and issue the required messages even when /STANDARD=PORTABLE is not specified.

A.1.24.2 Passing Narrow Types to Old Syntax Functions

Traditionally, a function written in C was always called with widened argument types. (Arguments of narrow types like char, short, or float were passed as the widened types int, int, and double, respectively.) The ANSI C Standard preserves this calling mechanism for functions declared using the old syntax. Functions declared using the new prototype syntax may be called with narrow argument types.

Tradition, however, did not specify how the compiler was to interpret a function definition that declared formal arguments of narrow type. One interpretation was that the widened types actually passed should be converted to the narrow type of the formal declaration by the function in its prologue. Another interpretation was that the compiler should rewrite the formal declarations to match the type of the argument actually passed. For example, under this second interpretation, the compiler would change a declaration of a formal argument of type float to a declaration of type double.

ANSI C has standardized the first interpretation of a function with formal arguments of narrow types. DEC C for OpenVMS Systems uses the ANSI C interpretation in all modes.

A.1.25 "Address of" Operator

In DEC C, if the argument of the unary & operator is an array, the result now has the type "pointer to array". Previously, in VAX C, the result would have the type "pointer to the element type of the array".

A.1.26 Unary Plus

DEC C supports the new ANSI C operator, unary plus (+). This operator returns the value of its operand (possibly widened by the integral promotions).

A.1.27 Relational Operators

As required by ANSI C, DEC C issues a warning (in all modes except VAX C mode) to diagnose a constraint violation if one of the operands of a relational operator is a pointer to a function. For example, the following code would issue a warning:

int (*f)();
if (f > NULL)

Note that it is valid to use the equality operators to compare function pointers.

A.1.28 Assignment Compatibility

ANSI C has tighter assignment compatibility rules than those previously enforced by VAX C. (Note that assignment compatibility rules also control function argument passing.) DEC C assignment compatibility differs from that of VAX C in the following ways:

A.1.29 Declarations

Function prototype support, the new const and volatile type qualifiers, and the void type, were already implemented in VAX C. The following sections describe the additional DEC C support that affects declarations. References are to the relevant sections in the ANSI C Standard.

A.1.29.1 Implementation Limits

The ANSI C Standard requires that an implementation support certain minimum requirements; these are listed in the referenced section. In those cases where VAX C imposes a fixed limit, that limit has always met or exceeded the Standard's requirements, and programs that exceed any of these limits elicit the appropriate errors. In strict ANSI C mode, DEC C now issues diagnostics against any source program constructs that exceed any of the Standard limits as well.

A.1.29.2 Identifier Name Length

In strict ANSI C mode, DEC C now issues diagnostic messages against declarations of external names in excess of six characters, or external names that are intended to denote different objects but that have the same spelling, and ignores alphabetical case.

A.1.29.3 Diagnosing Empty Declarations

The ANSI C Standard invalidates empty declarations, except for two special cases: one involving structure/union tags and the other involving the enumeration type. In strict ANSI C mode, DEC C issues an error message against any declaration that does not declare at least one of the following: a declarator, a tag, or the members of an enumeration.

A.1.29.4 Restriction on Placement of Storage-Class Specifiers

The ANSI C Standard specifies that allowing the placement of any storage-class specifier other than at the beginning of a declaration is an obsolete feature. In strict ANSI C mode, DEC C now issues an informational diagnostic to that effect when appropriate.

A.1.29.5 Diagnosing Old-Style Function Declarations

The ANSI C Standard specifies that old-style function declarations and definitions (that is, those not using the function prototype format) are obsolete. Old-style function declarations and definitions cause an informational message to be issued in all modes except VAX C.

A.1.29.6 Function Definitions Using typedef-names

The ANSI C Standard restricts the form of the declarator in a function definition: the function type itself may not be inherited from a typedef-name; that is, the declarator must explicitly contain a (possibly empty) parenthesized parameter list. If not, DEC C in strict ANSI C mode issues an error message.

A.1.29.7 Initialization

DEC C for OpenVMS Systems supports the initialization of unions.

In VAX C, an aggregate initializer consisting of a single item does not have to have the outer braces. The outer braces are required by the ANSI C Standard.

DEC C allows this case in VAX C mode.

A.1.30 Bit-Field Initialization

The DEC C compiler initializes bit-field structure members differently than VAX C does. See Section 4.7.2.

A.1.31 The Preprocessor

The following sections describe the differences between the VAX C and the DEC C preprocessors. Most of these differences reflect the DEC C preprocessor's conformance to the ANSI C Standard. References are to the relevant sections in the ANSI C Standard.

Note that most VAX C-specific preprocessor extensions are unaffected by these changes. These extensions continue to be supported quietly in VAX C mode, but elicit appropriate diagnostics in strict ANSI C mode.

A.1.31.1 White Space Appearing Before the #

The ANSI C Standard removes the VAX C restriction that requires the # character introducing a preprocessor directive to always appear in column 1 of the source line. In DEC C, white space and comments can now precede the # on the same line.

A.1.31.2 The #define Directive and Macro Substitution

Before the ANSI C Standard, the lack of a precise definition of the behavior of macro expansion led to a number of inconsistencies among different C implementations. DEC C, in adhering to the ANSI C Standard, removes these and many other discrepancies by specifying precisely how macro substitution is to be performed:

As required by the ANSI C Standard, DEC C supports two new operators that can appear only within macro definitions:

The ANSI C Standard also makes specific the sequence in which rescanning and further substitution is to take place, and under what conditions substitution does not take place. The ANSI C Standard also specifies under what circumstances a macro may be redefined: only benign redefinition is allowed, permitting a macro to be redefined only if the new definition is token-wise identical to the old definition.

A.1.31.3 The #line Directive

The ANSI C Standard specifies that macro substitution can occur on the operands of the #line directive, that the line number operand is restricted to the range 1 to 32,767, and that the file name operand must be treated as any character string literal. VAX C did not support macro substitution on this directive, performed no range checking on the line number, and restricted the length of the character string to 255.

DEC C supports macro substitution on the #line directive, diagnoses an out-of-range line number (in strict ANSI C mode only), and allows the file name character string to be as long as the maximum length supported by the compiler for ordinary strings. (Note that the ANSI C Standard requires support for a minimum of 509 characters in a string, and that DEC C supports strings up to 65,535 characters.)

A.1.31.4 The #error Directive

DEC C in both strict ANSI C mode and VAX C mode supports the new #error directive required by the ANSI C Standard.

A.1.31.5 The #pragma dictionary Directive

The #pragma dictionary preprocessor directive replaces the #dictionary directive, but the latter is still supported in VAX C mode for compatibility.

The #pragma dictionary and #dictionary preprocessor directives now allow you to specify whether all string data type variables should be null-terminated.

A.1.31.6 The #pragma extern_model Directive

The #pragma extern_model directive is added to control the compiler's interpretation of objects that have external linkage. This pragma lets you choose the global symbol model to be used for external variables.

A.1.31.7 The #pragma linkage Directive (Alpha only)

The #pragma linkage preprocessor directive allows you to specify special linkage types for function calls.

A.1.31.8 The #pragma use_linkage Directive (Alpha only)

The #pragma use_linkage directive associates a previously defined special linkage with a function.

A.1.31.9 The #pragma message Directive

The #pragma message directive controls the issuance of individual diagnostic messages or groups of messages. Use of this pragma overrides any command-line options that may affect the issuance of messages.

A.1.31.10 The #pragma module Directive

The #pragma module preprocessor directive replaces the #module directive, but the latter is still supported in VAX C mode for compatibility.


Previous Page | Next Page | Table of Contents | Index