Previous | Contents | Index |
An error is reported if, within a translation unit, the same identifier
appears with both internal and external linkage.
B.10 Types (§3.1.2.5)
The type
char
and the type
signed char
have the same representation and set of values. (If the unsigned
compile-time option is specified, then the types
char
and
unsigned char
have the same representation and set of values.)
B.11 Integer Constants (§3.1.3.2)
The digits 8 and 9 are permitted as valid octal digits in common C and
VAX C modes, but a warning message is issued.
B.12 Character Constants (§3.1.3.4)
A character constant containing more than one character or wide character is diagnosed with a warning under the error-checking compiler option and is stored as an integer value. A character constant with more than one character is represented with the last character in the low-order byte for compatibility with common C. Representation of an integer character constant containing an octal or hexadecimal escape sequence not in the basic execution character set is the value specified by the octal or hexadecimal number in the escape sequence. (Its value is interpreted as a signed or unsigned char , depending on whether the unsigned compile-time option is in effect.)
The type of a wide character constant,
wchar_t
, is
unsigned int
.
B.13 String Literals (§3.1.4)
The Standard states that identical string literals need not be
distinct, and any attempt to modify a string literal is undefined.
Therefore, it is an error to modify either a character-string literal
or wide-string literal.
B.14 Operators---Compound Assignment (§3.1.5)
The old form of compound assignment operators (such as =+, =-, =*, =/, and =%) are not defined in the Standard.1 Therefore, in expressions of the form expression =unary_op expression, where the =unary_op would previously have been interpreted as an assignment operator, the =unary_op is now interpreted as two tokens: the assignment operator and the unary_op.
A warning message is issued if the error-checking option is specified for =-, =*, =& and =+ (with no intervening white space) to remind you of this change in meaning. Without the error-checking option, no message is issued.
1 Early versions of C allowed compound assignment operators to be written in reverse form (=+, =-, = *) instead of the defined order (+=, -=, *=). This old form leads to syntactic ambiguities for the compound assignment operators whose second operator was also a valid unary operator. |
B.15 Characters and Integers---Value-Preserving Promotions (§3.2.1.1)
Two different approaches to the implementation of integer promotion rules have been taken by earlier versions of C. The first approach is called unsigned preserving, in which unsigned char and unsigned short widen to unsigned int . The second approach is called value preserving, in which unsigned char and unsigned short widen to signed int if the value can be represented; otherwise they widen to unsigned int . The Standard specifies that integer promotions are to be value-preserving. This approach is followed in all modes except common C and VAX C mode, and results in a quiet change to programs depending on unsigned-preserving arithmetic conversions.
To aid the programmer in locating arithmetic conversions that depend on
unsigned-preserving rules, any integer promotions of
unsigned char
and
unsigned short
to
int
that could be affected by the value-preserving approach for integer
promotions are flagged with the error-checking option.
B.16 Signed and Unsigned Integer Conversions (§3.2.1.2)
If the value of an integer demoted to a signed integer is too large to be represented, the result is truncated with excess high-order bits discarded. This is compatible with common C and VAX C.
Conversions between signed and unsigned integers of the same size
involve no representation change.
B.17 Floating and Integral Conversions (§3.2.1.3)
When an integer is converted to a floating-point number that cannot be represented exactly, the result of the conversion is the nearest value that can be represented exactly. This result is the natural result of the conversion on the hardware, and can be higher or lower than the original value.
When a floating-point number is converted at compile time to an integer or another floating-point type, and the result cannot be represented, the compiler issues a diagnostic message.
When an integral number or double floating-point number is converted to a floating-point number that cannot exactly represent the original value, the result is rounded to the nearest value of type float . (For details, see the architecture manual for your platform; for example, the MIPS R-Series Processor Architecture Manual or the VAX Architecture Manual.)
When demoting a double value to float , if the value being converted is in the range of values that can be represented, but not represented exactly, the result is the nearest higher or lower value. Compaq C rounds the result to the nearest representable float value.
Similar rounding is performed for demotions from
long double
to
double
or
float
.
B.18 Pointer Conversions (§3.2.2.3)
Even if two types have the same representation (such as int and long ), they are still different types. This means that a pointer to int cannot be assigned to a pointer to long without using a cast operation.
This rule is relaxed in the common C and VAX C modes. Pointer
conversions do not involve a representation change, but, because of
alignment restrictions on some machines, access through an unaligned
pointer can result in much slower access time, a machine exception, or
unpredictable results.
B.19 Structure and Union Members (§3.3.2.3)
The result of accessing a union member different than the member
holding a value depends on the data types of the members and their
alignment within the union.
B.20 The sizeof Operator (§3.3.3.4)
The type of the
sizeof
operator is
size_t
. Compaq C defines this type, which is the type of integer
required to hold the maximum size of an array, in the
<stddef.h>
header as
unsigned int
.
B.21 Cast Operators (§3.3.4)
The Standard specifies that a pointer can be converted to an integral type, but the size of the integer required and the result are implementation-defined. A pointer occupies the same amount of storage as objects of type int or long (or their unsigned equivalents). Therefore, a pointer can be converted to any of these integer types and back again without changing its value. No scaling takes place, and the representation of the value does not change.
Converting between a pointer and a shorter integer type, such as
char
, is similar to the conversion between an object of
unsigned long
type and a shorted integer type. The high-order bits of the pointer are
discarded. Converting between a shorter integer and a pointer is
similar to the conversion between the shorter integer type and
unsigned long
. The high-order bits of the pointer are filled with copies of the sign
bit if the shorter integer type was signed. Messages are issued for
cast operations of these types under the error-checking compiler option.
B.22 Multiplicative Operators (§3.3.5)
The Standard does not provide portable semantics for the division and remainder operators. Compaq C follows these semantics:
The compiler issues a warning in the following cases of undefined behavior detected at compile time:
Pointers to members of the same array can be subtracted. The result is
the number of elements between the two array members. The type of the
result is
ptrdiff_t
. Compaq C defines this type as
int
.
B.24 Bitwise Shift Operators (§3.3.7)
The result of
E1 >> E2
is
E1
right-shifted
E2
bit positions. If
E1
has a signed type, the value of the result is the shifted value of
E1
with the vacated high-order bits filled with a copy of
E1
's sign bit (arithmetic shift).
B.25 Storage-Class Specifiers (§3.5.1)
The
register
storage-class specifier suggests that access to the object be as fast
as possible.
Specifying
register
is intended to give a variable an increased probability of being stored
in a register. However, compiler register allocation techniques make
using the
register
keyword obsolete. That is, Compaq C accepts and ignores all
register
requests.
B.26 Type Specifiers (§3.5.2)
The combination
long float
is supported as a synonym for
double
for compatibility with common C and VAX C. This combination results in
a warning if compiled with the default mode or the strict ANSI mode.
B.27 Structure and Union Specifiers (§3.5.2.1)
The high-order bit position of an
int
bit field is not treated as a sign bit, except in the VAX C
compatibility mode. In other words, the type
int
designates the same type as
unsigned int
for all bit-field types. In VAX C mode, the type
int
designates the same type as
signed int
for all bit-field types.
B.28 Variant Structures and Unions
Variant structures and unions are VAX C extensions that allow nested structures and unions to be declared as members of the enclosing aggregate. This eliminates the need to specify an intermediate qualifier when referring to those members. These capabilities are only available in VAX C mode.
Your platform-specific Compaq C documentation contains details
about these extensions.
B.29 Structure Alignment
The alignment and size of a structure is affected by the alignment requirements and sizes of the structure components for each platform. A structure can begin on any byte boundary and occupy any integral number of bytes. However, individual architectures or operating systems can specify particular default alignment and padding requirements, which can be overridden by pragmas and command-line options.
On OpenVMS Alpha and Tru64 UNIX systems, nonbit-field structure members are, by default, aligned on natural boundaries.
The default alignment of a structure is the maximum alignment required by any member within the structure. The structure is padded to ensure that the size of a structure, in bytes, is a multiple of its alignment requirement to achieve the appropriate alignment when the structure or union is a member of an array.
The components of a structure are laid out in memory in the order they are declared. The first component has the same address as the entire structure. Padding is introduced between components to satisfy the alignment requirements of individual components.
A bit field can have any integral type. However, the compiler issues a warning with the error-checking option if the type is anything other than int , unsigned int , or signed int . The presence of bit fields causes the alignment of the whole structure or union to be at least the same as that of the bit field's base type.
Bit fields (including zero-length bit fields) not immediately declared following other bit fields have the alignment requirement imposed by their base type. Bit fields are allocated within the alignment unit (of the same size as the bit field's base type) from low-order to high-order.
With #pragma member_alignment in effect, if a bit field immediately follows another bit field, the bits are packed into adjacent space in the same unit, if sufficient space remains. Otherwise, padding is inserted at the end of the first bit field and the second bit field is put into the next unit.
With #pragma nomember_alignment in effect, bit fields are allowed to span storage unit boundaries. Alpha systems default to member_alignment while VAX systems default to nomember_alignment .
Bit fields of base type char cannot be larger than 8 bits. Bit fields of base type short cannot be larger than 16 bits.
OpenVMS VAX systems do not require that structures or structure members be aligned on any particular boundaries; nonbit-field structure members are byte-aligned by default.
The components of a structure are laid out in memory in the order they are declared. The first component has the same address as the entire structure. Each additional component follows its predecessor in the immediately following byte.
Natural alignment of structure members, can be obtained by using the following pragma:
pragma member_alignment |
The Compaq C User's Guide for OpenVMS Systems has examples and diagrams of OpenVMS VAX structure alignment.
Bit fields can have any integral type. However, the compiler issues a warning if /STANDARD=ANSI89 is specified, and the type is other than int , unsigned int , or signed int . Bit fields are allocated within the unit from low order to high order. If a bit field immediately follows another bit field, the bits are packed into adjacent space, even if this overflows into another byte. However, if an unnamed bit field is specified to have length 0, filler is added so the bit field immediately following starts on the next byte boundary.
The Compaq C User's Guide for OpenVMS Systems has examples and diagrams of OpenVMS VAX
bit-field alignment.
B.30 Enumeration Specifiers (§3.5.2.2)
The Standard specifies that each enumerated type be compatible with an
implementation-defined integer type. In Compaq C, each enumerated
type is compatible with the
signed int
type.
B.31 Type Qualifiers (§3.5.3)
The
volatile
storage class is specified for those variables that can be modified in
ways unknown to the compiler. Thus, if an object is declared volatile,
every reference to the object in the source code results in a reference
to memory in the object code.
B.32 Declarators (§3.5.4)
There is no internal limit on the number of pointer, function or array
declarators that can modify an arithmetic, structure, union, or
incomplete type.
B.33 Initialization (§3.5.7)
C allows initializers to be optionally surrounded by braces ( { } )
when they are not logically necessary. This has resulted in aggregate
initializers with partially ignored braces that are parsed differently
depending on the type of parser implemented (bottom-up or top-down).
The Standard has specified the top-down parse originally specified in
Kernighan and Ritchie's The C Programming Language. Programs
depending on a bottom-up parse (common C parse) of partially braced
initializers can yield unexpected results. Even though this construct
is allowed, a warning message is given to inform the user of ignored
braces when in common C mode or if using the check option.
B.34 The switch Statement (§3.6.4.2)
There is no limit on the number of
case
labels in a
switch
statement.
B.35 External Object Definitions (§3.7.2)
In common C mode, all
extern
objects have file scope.
B.36 Conditional Inclusion (§3.8.1)
Previous preprocessors have allowed extraneous text after a preprocessor directive. For example:
#endif system1 |
However, the Standard has stated that the only text allowed after a preprocessing directive is a comment. Therefore, the Compaq C compiler issues a warning message if this syntax rule is violated.
The numeric value for character constants within
#if
and
#elif
directives matches the value obtained when an identical character
constant occurs in expressions that are not part of these directives.
B.37 Source File Inclusion (§3.8.2)
Source files can be included using either a quoted path name (
#include "stdio.h"
) or bracketed path names (
#include <stdio.h>
). OpenVMS systems also support a method of including modules
from a text library.
See your platform-specific Compaq C documentation for the
search-path algorithm for including source files.
B.38 Macro Replacement---Predefined Macro Names (§3.8.3)
In addition to the predefined macro names defined in the Standard, the Compaq C compiler defines other preprocessor macros for various identification purposes. When the compiler is invoked, the appropriate identification macros are defined depending on the operating system, architecture, language, compiler mode, and other environment variables. You can reference these macros in #ifdef preprocessor directives to isolate code that applies to a particular environment.
Each Compaq C platform can have additional predefined macros. See your platform-specific Compaq C documentation for more information.
Table B-1 shows the predefined macro names for Tru64 UNIX.
Macro Name | |
---|---|
Operating system name: | unix |
__unix__ | |
__osf | |
SYSTYPE_BSD | |
_SYSTYPE_BSD | |
Architecture name: | __alpha |
Product name: | __DECC |
__DECC_VER | |
LANGUAGE_C | |
__LANGUAGE_C__ |
Table B-2 shows the predefined macro names for OpenVMS VAX and Alpha systems. All forms are defined unless strict ANSI mode is in effect, in which case only the new spellings are defined.
New Spelling | Traditional Spelling | |
---|---|---|
Operating system name: | __vms | vms |
__VMS | VMS | |
__vms_version | vms_version | |
__VMS_VERSION | VMS_VERSION | |
Architecture name: | __vax (VAX) | vax (VAX) |
__VAX (VAX) | VAX (VAX) | |
__alpha (ALPHA) | --- | |
__ALPHA (ALPHA) | --- | |
__Alpha_AXP (ALPHA) | --- | |
__32BITS (ALPHA) | --- | |
Product name: | __vaxc | vaxc |
__VAXC | VAXC | |
__vax11c | vax11c | |
__VAX11C | VAX11C | |
__STDC__ | --- | |
__DECC | --- | |
__DECC_VER | --- | |
__VMS_V6_RTL_COMPAT | --- | |
Compiler Mode: | __DECC_MODE_STRICT | --- |
__DECC_MODE_RELAXED | --- | |
__DECC_MODE_VAXC | --- | |
__DECC_MODE_COMMON | --- | |
Floating-Point: | __D_FLOAT | --- |
__G_FLOAT | --- | |
__IEEE_FLOAT (ALPHA) | --- | |
__X_FLOAT (ALPHA) | --- | |
Other: | __HIDE_FORBIDDEN_NAMES | --- |
__INITIAL_POINTER_SIZE (ALPHA) | --- |
You can explicitly define the macros in Table B-3 to control which C library routines are declared in header files and to obtain standards conformance checking. To define these macros use one of the following:
Macro | Standard |
---|---|
_XOPEN_SOURCE_EXTENDED | XPG4-UNIX |
_XOPEN_SOURCE | XPG4 |
_POSIX_C_SOURCE | POSIX |
_ANSI_C_SOURCE | ISO C and ANSI C |
_AES_SOURCE (TRU64 UNIX) | Application Environment Services |
_OSF_SOURCE (TRU64 UNIX) | OSF compatibility |
_VMS_V6_SOURCE (OPENVMS) | OpenVMS Version 6 compatibility |
_DECC_V4_SOURCE (OPENVMS) | DEC C Version 4 compatibility |
Previous | Next | Contents | Index |