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:
To help developers reduce the amount of memory used by dynamically allocated pointers
To assist with the porting of applications that contain assumptions about the sizes of pointers
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.
The following list defines pointer terminology used in this appendix:
Short pointer: A 32-bit pointer. When a short pointer is declared, 32 bits are allocated.
Long pointer: A 64-bit pointer. When a long pointer is declared, 64 bits are allocated. This is the default pointer type on Tru64 UNIX systems.
Simple pointer: A pointer to a nonpointer data type,
for example,
int *num_val;.
More specifically, the pointed-to type contains no
pointers, so the size of the pointed-to type does not depend on the size of
a pointer.
Compound pointer: A pointer to a data type whose size depends
upon the size of a pointer, for example,
char **FontList.
Two
cc
options and a set of pragmas control the use
of 32-bit pointers.
The
cc
options for controlling pointer size are:
-xtaso
Enables recognition of the
#pragma pointer_size
directive and causes
-taso
to be passed to the
linker (if linking).
-xtaso_short
Enables recognition of the
#pragma pointer_size
directive, sets the initial compiler state to use short pointers,
and passes
-taso
to the linker (if linking).
Because all system routines continue to use 64-bit pointers, most applications
require source changes when compiled in this way.
However, the use of
protect_headers_setup(8)
can greatly reduce or eliminate the need for source code changes.
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
#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
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.
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).
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 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.
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.
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.
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.