|
|
HP C
|
Previous | Contents | Index |
Modules must be linked to the appropriate run-time library. For more information about linking against the HP C RTL shareable image and object libraries, see the HP C Run-Time Library Reference Manual for OpenVMS Systems. |
Table 4-2 shows the supported floating-point formats, and their approximate sizes and range of values.
When running the compiler in VAX C mode, relaxed pointer and pointer/integer compatibility is allowed. That is, all pointer and integer types are compatible, and pointer types are compatible with each other regardless of the type of the object they point to. Therefore, in VAX C mode, a pointer to float is compatible with a pointer to int . This is not true in ANSI C mode.
Although pointer conversions do not involve a representation change when compiling in VAX C mode, 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.
The alignment and size of a structure is affected by the alignment requirements and sizes of the structure components for each HP C 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 alignment and padding requirements.
HP C on VAX processors does not require that structures or structure members be aligned on any particular boundaries.
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. On VAX processors, each additional component follows its predecessor in the immediately following byte.
For example, the following type is aligned as shown in Figure 4-1:
struct {char c1; short s1; float f; char c2; } |
Figure 4-1 VAX Structure Alignment
The alignment of the entire structure can occur on any byte boundary, and no padding is introduced. The float variable f may span longwords, and the short variable s1 may span words.
The following pragma can be used to force specific alignments:
#pragma member_alignment |
Structure alignment for HP C for OpenVMS Systems on VAX processors is achieved by the default, #pragma nomember_alignment , which causes data structure members to be byte-aligned (with the exception of bit-field members).
Structure alignment for HP C for OpenVMS Systems on Alpha and Itanium processors is achieved by the default, #pragma member_alignment , which causes data structure members to be naturally aligned. This means that data structure members are aligned on the next boundary appropriate to the type of the member, rather than on the next byte.
For more information on the #pragma member_alignment preprocessor directive, see Section 5.4.13.
Bit fields can have any integral type. However, the compiler issues a warning if /STANDARD=ANSI89 is specified, and the type is something 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.
For example, the following type is aligned as shown in Figure 4-2:
struct {int i:2; int ii:2; unsigned int ui: 30; } |
Figure 4-2 OpenVMS Bit-Field Alignment
Bit field ii is positioned immediately following bit field i . Because there are only 28 bit positions remaining and ui requires 30 bits, the first 28 bits of ui are put into the first longword, and the remaining two bits overflow into the next longword.
The HP C compiler initializes bit fields in struct s differently than VAX C does. The following program compiles without error using both compilers but the results are different. HP C skips over unnamed bits but VAX C does not.
#include <stdio.h> int t() { static struct bar {unsigned :1; unsigned one : 1; unsigned two : 1; }; struct bar foo = {1,0}; printf("%d %d\n",foo.one,foo.two); return 1; } |
When compiled with HP C, this example produces the following output:
1 0 |
When compiled with VAX C, this example produces the following output:
0 0 |
Variant structures and unions are HP C extensions available in VAX C compatibility mode only, and they are not portable.
Variant structure and union declarations allow you to refer to members of nested aggregates without having to refer to intermediate structure or union identifiers. When a variant structure or union declaration is nested within another structure or union declaration, the enclosed variant aggregate ceases to exist as a separate aggregate, and HP C propagates its members to the enclosing aggregate.
Variant structures and unions are declared using the variant_struct and variant_union keywords. The format of these declarations is the same as that for regular structures or unions, with the following exceptions:
Initialization of a variant structure or union is the same as that for a normal structure or union.
As with regular structures and unions, in VAX C compatibility mode, variant structures and unions in an assignment operation need only have the same size in bits, rather than requiring the same members and member types.
To show the use of variant aggregates, consider the following code example that does not use variant aggregates:
/* The numbers to the right of the code represent the byte offset * * from the enclosing structure or union declaration. */ struct TAG_1 { int a; /* 0-byte enclosing_struct offset */ char *b; /* 4-byte enclosing_struct offset */ union TAG_2 /* 8-byte enclosing_struct offset */ { int c; /* 0-byte nested_union offset */ struct TAG_3 /* 0-byte nested_union offset */ { int d; /* 0-byte nested_struct offset */ int e; /* 4-byte nested_struct offset */ } nested_struct; } nested_union; } enclosing_struct; |
If you want to access nested member d , then you need to specify all the intermediate aggregate identifiers:
enclosing_struct.nested_union.nested_struct.d |
If you try to access member d without specifying the intermediate identifiers, then you would access the incorrect offset from the incorrect structure. Consider the following example:
enclosing_struct.d |
The compiler uses the address of the original structure ( enclosing_struct ), and adds to it the assigned offset value for member d (0 bytes), even though the offset value for d was calculated according to the nested structure ( nested_struct ). Consequently, the compiler accesses member a (0-byte offset from enclosing_struct ) instead of member d .
The following code example shows the same code using variant aggregates:
/* The numbers to the right of the code present the byte offset * * from enclosing_struct. */ struct TAG_1 { int a; /* 0-byte enclosing_struct offset */ char *b; /* 4-byte enclosing_struct offset */ variant_union { int c; /* 8-byte enclosing_struct offset */ variant_struct { int d; /* 8-byte enclosing_struct offset */ int e; /* 12-byte enclosing_struct offset */ } nested_struct; } nested_union; } enclosing_struct; |
The members of the nested_union and nested_struct variant aggregates are propagated to the immediately enclosing aggregate ( enclosing_struct ). The variant aggregates cease to exist as individual aggregates.
Since the nested_union and nested_struct variant aggregates do not exist as individual aggregates, you cannot use tags in their declarations, and you cannot use their identifiers ( nested_union , nested_struct ) in any reference to their members. However, you are free to use the identifiers in other declarations and definitions within your program.
To access member d , use the following notation:
enclosing_struct.d |
Using the following notation causes unpredictable results:
enclosing_struct.nested_union.nested_struct.d |
If you use normal structure or union declarations within a variant aggregate declaration, the compiler propagates the structure or union to the enclosing aggregate, but the members remain a part of the nested aggregate. For example, if the nested structure in the last example was of type struct , the following offsets would be in effect:
struct TAG_1 { int a; /* 0-byte enclosing_struct offset */ char *b; /* 4-byte enclosing_struct offset */ variant_union { int c; /* 8-byte enclosing_struct offset */ struct TAG_2 /* 8-byte enclosing-struct offset */ { int d; /* 0-byte nested_struct offset */ int e; /* 4-byte nested_struct offset */ } nested_struct; } nested_union; } enclosing_struct; |
In this case, to access member d , use the following notation:
enclosing_struct.nested_union.nested_struct.d |
The following sections describe program-section attributes and program sections created by HP C for OpenVMS Systems.
As the HP C compiler creates an object module, it groups data into contiguous program sections, or psects. The grouping depends on the attributes of the data and on whether the psects contain executable code or read/write variables.
The compiler also writes into each object module information about the program sections contained in it. The linker uses this information when it binds object modules into an executable image. As the linker allocates virtual memory for the image, it groups together program sections that have similar attributes.
Table 4-3 lists the attributes that can be applied to program sections.
If necessary, HP C creates the following program sections:
All program sections created by HP C have the PIC, REL, RD, USR, and NOVEC attributes. On VAX systems, the $CODE psect is aligned on a byte boundary; all other psects generated by HP C are aligned on longword boundaries. On OpenVMS Alpha and I64 systems, all psects generated by HP C are aligned on octaword boundaries. Note that use of the _align storage-class modifier can cause a psect to be aligned on greater than a longword boundary on OpenVMS VAX systems. The $CHAR_STRING_CONSTANTS psect has the same attributes as the $DATA (VAX ONLY) and $DATA$ (ALPHA, I64) psects.
Tables 4-4, 4-5, 4-6, and 4-7 summarize the differences in psects created by different declarations:
Previous | Next | Contents | Index |
|