The Digital UNIX C compiler supports the use of 32-bit pointers on the 64-bit Digital UNIX operating system. All system interfaces use 64-bit pointers. The 32-bit pointer data type is provided to help developers reduce the amount of memory used by dynamically allocated pointers and to assist with the porting of applications that contain assumptions about the sizes of pointers. The use of 32-bit pointers in applications requires source code modifications and the use of compiler options.
The following list defines pointers described in this appendix:
Two cc flags and a set of pragmas control the usage of 32-bit pointers. The -xtaso compiler flag causes the compiler to respond to the #pragma pointer_size directives. The -xtaso_short compiler flag causes the compiler to allocate 32-bit pointers by default and is recognized only when used with the -xtaso flag.
The cc flags for controlling pointer size are the following:
Enables the use of short pointers. All pointer types default to long pointers, but short pointers can be declared through the use of the pointer_size pragmas.
Enables the use of short pointers. All pointer types default to short pointers. Long pointers can be declared through the use of the pointer_size pragmas. Because all system routines continue to use 64-bit pointers, most applications require source changes when used in this way.
Within a C program, the size of pointer types can be controlled by the use of pragmas. These pragmas are only recognized by the compiler if the -xtaso or -xtaso_short flags have been specified with the cc command; they are silently ignored if neither of the flags are specified. Pointer sizes specified by the following pragmas override the default pointer size.
The #pragma pointer_size specifier 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 | All pointer sizes following this pragma are long pointers (64 bits in length) until an overriding pointer_size pragma is encountered. |
short | 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 such that a corresponding #pragma pointer_size restore will set the pointer size to the current value. The model for pointer size preservation is a last-in, first-out stack such that a save is analogous to a push, and a restore is analogous to a pop. |
restore |
The opposite of
save.
Restore the uppermost 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 -xtaso flag causes the compiler to respond to the #pragma pointer_size directives. The -xtaso_short compiler flag causes the compiler to allocate 32-bit pointers by default.
The following example demonstrates the use of both short and long pointers:
#include <stdio.h> /* modified with #pragma pointer_size */ main ()
{ int *a_ptr;
printf ("A pointer is %ld bytes\n", sizeof (a_ptr)); }
When compiled either with default settings or with the -xtaso flag, the sample program prints the following:
A pointer is 8 bytes
When compiled with the -xtaso_short flag, this sample program prints the following:
A pointer is 4 bytes
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.
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. Thus, 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.
The alignment and padding rules for short pointers in structures are the same as for long pointers; the only difference is in the sizes of the pointers.
To use short pointers, the virtual address space in which the application runs must be constrained such that all valid pointer values are representable in 31 bits. The -taso linker flag enforces this constraint. Applications that use the -xtaso compiler flag must be linked with the -taso option.
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.
Because Digital 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, explicit conversion of the short pointers to long pointers can be required.
Conversion of pointers can be either explicit or implicit. An explicit conversion occurs when the value of a short pointer is assigned to a long pointer, or vice versa. An implicit conversion occurs when a short pointer is passed as an argument to a function that expects long pointers, or vice versa. Implicit conversions only work correctly on simple pointers; complex pointers (pointers to pointers) require explicit conversions.
In general, the conversion of complex pointers requires source code changes. Alignment and segmentation faults result if complex pointers are not correctly converted.
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.
The pointer_size short pragma has no effect on the size of the second argument to main(), traditionally called argv. This pragma always has a size of 8 bytes even if the pragma has been used to set other pointer sizes to 4 bytes.
All Digital UNIX system routines operate on 64-bit pointers, so all system routine declarations must be made in the context of a #pragma pointer_size long declaration.
You can avoid extensive modification of existing applications by modifying all of the system header files on your Digital UNIX system by doing the following:
#pragma pointer_size (save) #pragma pointer_size (long)
#pragma pointer_size (restore)
The following example scripts modify the system header files to declare correctly all system routines that use long pointers. Before using these scripts, be sure to back up your system disk.
To use these scripts, create the following files in one directory and change their permissions to execute. Then run the xtaso_header_edit script with no arguments; it is automated and will modify all header files. You must be superuser on the system on which you want to perform the modifications.
xtaso_header_edit: ------------------ #!/bin/csh find /usr/include ! -type l -name '*.h' \ -exec short_pointer-sed.csh {} \; find /sys/include ! -type l -name '*.h' \ -exec short_pointer-sed.csh {} \;
short_pointer-sed.csh: --------------------- #!/bin/csh echo $1 sed -f short_ptr.sed $1 >/tmp/short_ptr.tmp mv /tmp/short_ptr.tmp $1
short_ptr.sed: ------------- 1i \ #pragma pointer_size save 1i \ #pragma pointer_size long $a \ #pragma pointer_size restore
Because most applications on Digital UNIX systems use addresses that are not representable in 32 bits, the use of a short pointer in these applications would 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 Digital UNIX first and then analyzed to see if short pointers would be of benefit.
The -taso linker option that is required to link programs that make use of short pointers imposes additional restrictions on the run-time environment and how libraries may be used. See cc(1) for more information on the -taso option.