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:
int
*num_val;
.
char
*argv[]
or
char
**FontList
.
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:
-xtaso
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.
-xtaso_short
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.