A    Using 32-Bit Pointers on Tru64 UNIX Systems

The Tru64 UNIX C compiler supports the use of 32-bit pointers on the 64-bit Tru64 UNIX operating system. All system interfaces use 64-bit pointers. The 32-bit pointer data type is supported for the following reasons:

The use of 32-bit pointers in applications requires that the applications be compiled and linked with special options and, depending on the specific nature of the code, may also require source-code changes.

A.1    Pointer Definitions

The following list defines pointer terminology used in this appendix:

A.2    Using 32-Bit Pointers

Two cc options and a set of pragmas control the use of 32-bit pointers.

The cc options for controlling pointer size are:

The size of pointer types can be controlled by the use of pragmas within a C program. These pragmas are recognized by the compiler only if the -xtaso or -xtaso_short options are specified on the cc command line; they are ignored if neither of the options are specified.

The #pragma  pointer_size directive provides control over pointer size allocation. This pragma has the following syntax:

#pragma pointer_size specifier

The specifier argument must be one of the following keywords:

long | 64 All pointer sizes following this pragma are long pointers (64 bits in length) until an overriding pointer_size pragma is encountered.
short | 32 All pointer sizes following this pragma are short pointers (32 bits in length) until an overriding pointer_size pragma is encountered.
save Save the current pointer size. A corresponding #pragma pointer_size  restore will set the pointer size to the saved value. The model for pointer size preservation is a last-in, first-out stack; a save is analogous to a push and a restore is analogous to a pop.
restore

The opposite of save. Restore the most recently saved pointer size and delete it from the save/restore stack. For example:

 #pragma pointer_size long
   /* pointer sizes in here are 64-bits */
 #pragma pointer_size save
 #pragma pointer_size short
   /* pointer sizes in here are 32-bits */
 #pragma pointer_size restore
   /* pointer sizes in here are again 64-bits */

The following example demonstrates the use of both short and long pointers:

   main ()
 
  {
     int *a_ptr;
 
     printf ("A pointer is %ld bytes\n", sizeof (a_ptr));
  }

When compiled either with default settings or with the -xtaso option, the sample program prints the following message:

A  pointer  is  8  bytes

When compiled with the -xtaso_short option, this sample program prints the following message:

A  pointer  is  4  bytes

A.3    Syntactic Considerations

The size of pointers within macros is governed by the context in which the macro is expanded. There is no way to specify pointer size as part of a macro other than by using a typedef declared with the desired pointer size.

The size of pointers used in a typedef that includes pointers as part of its definition is determined when the typedef is declared, not when it is used. Therefore, if a short pointer is declared as part of a typedef definition, all variables that are declared using that typedef will use a short pointer, even if those variables are compiled in a context where long pointers are being declared.

A.4    Requirements

To use short pointers, the virtual address space in which the application runs must be constrained so that all valid pointer values are representable in 31 bits. The -taso linker option enforces this constraint. Applications that use either the -xtaso or -xtaso_short compiler options must be linked with the -taso option. See cc(1) for more information on the -taso linker option. If the cc command is used to perform the link, either -xtaso or -xtaso_short will cause -taso to be passed to the linker (ld).

A.5    Interaction with Other languages

Only the C compiler supports the use of short pointers. Short pointers should not be passed from C routines to routines written in other language.

A.6    Conversion of Pointers and Other Issues

Because Tru64 UNIX is a 64-bit system, all applications must use 64-bit pointers wherever pointer data is exchanged with the operating system or any system-supplied libraries. Because normal applications use the standard system data types, no conversion of pointers is needed. In an application that uses short pointers, it may be necessary to explicitly convert the short pointers to long pointers.

A.6.1    Pointer Conversion

In general, conversions between short and long simple pointers are safe and are performed implicitly without the need for casts on assignments or function calls. On the other hand, compound pointers generally require source code changes to accommodate conversions between short and long pointer representations.

For example, the argument vector, argv, is a compound long pointer, and must be declared as such. Many X11 library functions return compound long pointers; the return values for these functions must be declared correctly or erroneous behavior will result. If a function was compiled to exclusively use short pointers and needed to access such a vector, it would be necessary to add code to copy the values from the long pointer vector into a short pointer vector before passing it to the function.

The pointer_size pragma and the -xtaso_short option have no effect on the size of the second argument to main(), traditionally called argv. This argument always has a size of 8 bytes even if the pragma has been used to set other pointer sizes to 4 bytes.

A.6.2    System Header Files

When the system libraries are built, the compiler assumes that pointers are 64 bits and that structure members are naturally aligned. These are the C and C++ compiler defaults. The interfaces to the system libraries (the header files in the /usr/include tree) do not explicitly encode these assumptions.

You can alter the compiler's assumptions about pointer size (with -xtaso_short) and structure member alignment (with -Zpn [where n!=8] or -nomember_alignment). If you use any of these options and your application includes a header file from the /usr/include tree and then calls a library function or uses types declared in that header file, problems may occur. In particular, the data layouts computed by the compiler when it processes the system header file declarations may differ from the layouts compiled into the system libraries. This situation can cause unpredictable results.

Run the script protect_headers_setup.sh immediately after the compiler is installed on your system to eliminate the possibility of problems with pointer size and data alignment under the conditions described in this section. See protect_headers_setup(8) for details on how and why this is done.

You can enable or disable the protection established by the protect_headers_setup script by using variations of the -protect_headers option on your compilation command line. See cc(1) for information on the -protect_headers option.

A.7    Restrictions

Because most applications on Tru64 UNIX systems use addresses that are not representable in 32 bits, the use of a short pointer in these applications will cause these applications to fail. Thus, no library that might be called by normal applications can contain short pointers. Vendors of software libraries generally should not use short pointers.

Because the use of short pointers, in general, requires understanding and knowledge of the application they are applied to, they are not recommended as a porting aid. Applications for which you are considering the use of short pointers should be ported to Tru64 UNIX first and then analyzed to see if short pointers would be of benefit.

The -taso linker option, which is required to link programs that make use of short pointers, imposes additional restrictions on the run-time environment and how libraries can be used. See cc(1) for more information on the -taso option.