|
|
HP C
|
Previous | Contents | Index |
The dollar sign ($) is not an element of the minimum basic character set allowed by the C standard. By a systemwide convention, the dollar sign identifies HP reserved identifiers. HP 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.
In HP C, null arguments to a macro produce a BUGCHECK. VAX C allowed macro arguments to be null.
Standard 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 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 HP C to add additional macros, variables, and functions to the standard-specified header files, such as <stdio.h>.
The following sections describe how HP C solves the reserved name space problem for extensions involving keywords, predefined macros, and header file contents.
VAX C has several keywords that intrude into the user name space. The HP 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 HP 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 mode without eliciting syntax errors. In relaxed 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 standard-conforming pragmas.
Alternate spellings that follow standard C rules are added to HP 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 C standard's rules about the name space, and does not recognize the old spellings as predefined macros. You are encouraged to use the new standard C conformant spelling of the macros.
Table A-3 shows the traditional spelling and the new spelling of the predefined macros affected
The 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 HP 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 _FORBIDDEN_NAMES #define TRUE 1 #endif |
HP C for OpenVMS Systems supports the following new system-identification macros:
The following sections describe changes to the data types supported by HP C.
HP 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.
Standard 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 HP 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 HP 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.
In VAX C, long float is a synonym for double. Since the C Standard retires the long float specification, HP 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.
On OpenVMS VAX systems, HP C maps the standard 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.
HP 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:
#ifndef __INTS_LOADED #define __INTS_LOADED 1 /**************************************************************************** ** ** <ints.h> - Definitions for platform specific integer types ** ***************************************************************************** ** Header is nonstandard ***************************************************************************** #pragma __nostandard /* ** Ensure that the compiler will not emit diagnostics about "signed" ** keyword usage when in /STAND=VAXC mode (the reason for the diagnostics ** is that VAX C does not support the signed keyword). */ #if ((__DECC_VER >= 50600000) && !defined(__DECCXX)) # pragma __message __save # pragma __message __disable (__SIGNEDKNOWN) typedef signed char int8; typedef unsigned char uint8; # pragma __message __restore #else typedef signed char int8; typedef unsigned char uint8; #endif /* ** Define 16 and 32 bit integer types */ #if defined(__DECC) || (defined(__DECCXX) && defined(__ALPHA)) typedef __int16 int16; typedef unsigned __int16 uint16; typedef __int32 int32; typedef unsigned __int32 uint32; #else typedef short int int16; typedef unsigned short int uint16; typedef int int32; typedef unsigned int uint32; #endif /* ** Define 64 bit integer types only on Alpha */ #ifdef __ALPHA typedef __int64 int64; typedef unsigned __int64 uint64; #endif #pragma __standard #endif /* __INTS_LOADED */ |
HP C for OpenVMS Systems in strict and relaxed mode uses different rules than HP C in VAX C mode to determine if two types are identical:
These rules cause the strict and relaxed modes to be much more strict than VAX C mode about type checking.
As required by the C standard, HP 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 C Standard). However, a redeclaration is done.
Since the composite type feature of the 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 HP C in VAX C mode.
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, HP C does not treat enumerations as a special type.
As specified by standard C, HP C floating-point constants suffixed by l or L have type long double. (Currently, VAX C gives such constants type double).
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. (VAX ONLY)
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. (VAX ONLY)
The type of an unsuffixed decimal integer constant is the first type in the following list that can represent its value: int, long int, unsigned long int (only in VAXC, COMMON, ANSI89, and MIA modes), long long int, unsigned long int. (ALPHA ONLY)
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, unsigned long int, long long int, unsigned long long int. (ALPHA ONLY)
For more information, see the Integer Constants section in Chapter 1 of the HP C Language Reference Manual.
To meet the needs of non-European languages with large character sets, the C standard 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.
Standard 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, Standard C supports a fixed-size representation where each character is stored in the same number of bytes. This representation is called wide character support. HP C supports a new form of wide character constant and wide string literal.
Standard 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>.
HP C defines wchar_t to be unsigned int. This allows all character sets supported by ISO 10646 to be supported simultaneously.
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.
As required by standard C, HP 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 HP C RTL mbtowc function to convert the multibyte character into a wide character. The resulting value has type wchar_t.
As required by the C Standard, HP 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 HP C RTL mbstowcs function to convert the multibyte characters into wide characters. The resulting wide character string literal has type array of wchar_t.
In HP 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.
As required by the C Standard, HP 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.
Standard 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 HP C compiler in VAX C mode allows the cast operator to produce an lvalue.
The following sections describe changes to function calls.
Standard 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 standard C. For example, two structs are assignment-compatible in VAX C only if they are the same size.
The HP C compiler in VAX C mode and common mode is compatible with VAX C in assignment compatibility rules. Other modes follow the stricter standard C rules, documented in Section A.1.27 of this guide, and issue the required messages even when /STANDARD=PORTABLE is not specified.
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 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.
Standard C has standardized the first interpretation of a function with formal arguments of narrow types. HP C for OpenVMS Systems uses the standard C interpretation in all modes.
Previous | Next | Contents | Index |
|