HP C
Run-Time Library Reference Manual for OpenVMS Systems


Previous Contents Index

1.10.4.4 Functions Requiring Explicit use of 64-Bit Structures

Some functions require explicit use of 64-bit structures when compiling /POINTER_SIZE=LONG. This is necessary for functions that have recently had 64-bit support added to avoid unexpected runtime errors by inadvertently mixing 32-bit and 64-bit versions of structures.

Consider the following functions:


getaddrinfo        getpwnam 
freeaddrinfo       getpwnam_r 
getpwuid           getpwent 
sendmsg            getpwent_r 
recvmsg            

These functions previously offered 32-bit support only, even when compiled with /POINTER_SIZE=LONG. In order to preserve the previous behavior of 32-bit pointer support in those functions even when compiled with /POINTER_SIZE=LONG, these seven functions do not follow the normal convention for 32-bit and 64-bit support as documented in the previous section.

The following variants of these functions, and the corresponding structures they use, have been added to the C RTL to provide 64-bit support:


Function                        Structure 
--------                        --------- 
__getaddrinfo32                 __addrinfo32 
__getaddrinfo64                 __addrinfo64 
__freeaddrinfo32                __addrinfo32 
__freeaddrinfo64                __addrinfo64 
__recvmsg32                     __msghdr32 
__recvmsg64                     __msghdr64 
__sendmsg32                     __msghdr32 
__sendmsg64                     __msghdr64 
__32_getpwnam                   __passwd32 
__64_getpwnam                   __passwd64 
 
_getpwnam_r32 __passwd32 
_getpwnam_r64 __passwd64 
 
__32_getpwuid                   __passwd32 
__64_getpwuid                   __passwd64 
 
_getpwuid_r32  __passwd32 
_getpwuid_r64  __passwd64 
 
__32_getpwent                   __passwd32 
__64_getpwent                   __passwd64 

When compiling the standard versions of these functions, the following behavior occurs:

However, a similar conversion of the corresponding structures does not occur for these functions. This behavior is necessary because these structures existed before OpenVMS Version 7.3-2 as 32-bit versions only, even when compiled with /POINTER_SIZE=LONG. Implicitly changing the size of the structure could result in unexpected run-time errors.

When compiling programs that use the standard version of these functions for 64-bit support, you must use the 64-bit-specific definition of the related structure. With /POINTER_SIZE=64 specified, compiling a program with the standard function name and standard structure definition will result in compiler PTRMISMATCH warning messages.

For example, the following program uses the getaddrinfo and freeaddrinfo routines, along with the standard definition of the addrinfo structure. Compiling this program results in the warning messages shown:


$ type test.c 
#include <netdb.h> 
 
int main () 
{ 
    struct addrinfo *ai; 
 
    getaddrinfo ("althea", 0, 0, &ai); 
    freeaddrinfo (ai); 
    return 0; 
} 
 
$ cc /pointer_size=64 TEST.C 
 
    getaddrinfo ("althea", 0, 0, &ai); 
....^ 
%CC-W-PTRMISMATCH, In this statement, the referenced type of the pointer value 
"&ai" is "long pointer to struct addrinfo", which is not compatible with "long 
pointer to struct __addrinfo64". 
at line number 7 in file TEST.C;1 
 
    freeaddrinfo (ai); 
....^ 
%CC-W-PTRMISMATCH, In this statement, the referenced type of the pointer value 
"ai" is "struct addrinfo", which is not compatible with "struct __addrinfo64". 
at line number 8 in file TEST.C;1 
$ 

When compiling for 64 bits, you need to use the 64-bit-specific version of the related structure. In the previous example, the declaration of the ai structure could be changed to the following:


struct __addrinfo64 *ai; 

Or, to provide flexibility between 32-bit and 64-bit compilations, the ai structure could be declared as follows:


#if __INITIAL_POINTER_SIZE == 64 
    struct __addrinfo64 *ai; 
#else 
    struct __addrinfo32 *ai; 
#endif 

1.10.4.5 Functions Restricted to 32-Bit Pointers

A few functions in the HP C RTL do not support 64-bit pointers. If you try to pass a 64-bit pointer to one of these functions, the compiler generates a %CC-W-MAYLOSEDATA warning. Applications compiled with /POINTER_SIZE=64 might need to be modified to avoid passing 64-bit pointers to these functions.

Table 1-8 shows the functions restricted to using 32-bit pointers. The HP C RTL offers no 64-bit support for these functions. You must ensure that only 32-bit pointers are used with these functions.

Table 1-8 Functions Restricted to 32-Bit Pointers
atexit frexp ioctl setbuf
execv getopt modf setstate
execve iconv putenv setvbuf
execvp initstate    

Table 1-9 shows functions that make callbacks to user-supplied functions as part of processing that function call. The callback procedures are not passed 64-bit pointers.

Table 1-9 Callbacks that Pass Only 32-Bit Pointers
decc$from_vms decc$to_vms
ftw tputs

1.10.5 Reading Header Files

This section introduces the pointer-size manipulations used in the HP C RTL header files. Use the following examples to become more proficient in reading these header files and to help modify your own header files.


Examples

#1

: 
#if __INITIAL_POINTER_SIZE (1)
#   if (__VMS_VER < 70000000) || !defined __ALPHA (2)
#      error " Pointer size usage not permitted before OpenVMS Alpha V7.0" 
#   endif 
#   pragma __pointer_size __save (3)
#   pragma __pointer_size 32 (4)
#endif 
: 
: 
#if __INITIAL_POINTER_SIZE (5)
#   pragma __pointer_size 64 
#endif 
: 
: 
#if __INITIAL_POINTER_SIZE (6)
#   pragma __pointer_size __restore 
#endif 
: 
 
 
      

All HP C compilers that support the /POINTER_SIZE qualifier predefine the __INITIAL_POINTER_SIZE macro. The HP C RTL header files take advantage of the ANSI rule that if a macro is not defined, it has an implicit value of 0.

The macro is defined as 32 or 64 when the /POINTER_SIZE qualifier is used. It is defined as 0 if the qualifier is not used. The statement at (1) can be read as "if the user has specified either /POINTER_SIZE=32 or /POINTER_SIZE=64 on the command line".

The C compiler is supported on many OpenVMS versions. The lines at (2) generate an error message if the target of the compilation is one that does not support 64-bit pointers.

A header file cannot assume anything about the actual pointer-size context in effect at the time the header file is included. Furthermore, the HP C compiler offers only the __INITIAL_POINTER_SIZE macro and a mechanism to change the pointer size, but not a way to determine the current pointer size.

All header files that have a dependency on pointer sizes are responsible for saving (3), initializing (4), altering (5), and restoring (6) the pointer-size context.

#2

: 
#ifndef __CHAR_PTR32 (1)
#   define __CHAR_PTR32 1 
    typedef char * __char_ptr32; 
    typedef const char * __const_char_ptr32; 
#endif 
: 
: 
#if __INITIAL_POINTER_SIZE 
#   pragma __pointer_size 64 
#endif 
: 
: 
#ifndef __CHAR_PTR64 (2)
#   define __CHAR_PTR64 1 
    typedef char * __char_ptr64; 
    typedef const char * __const_char_ptr64; 
#endif 
: 
 
 
      

Some function prototypes need to refer to a 32-bit pointer when in a 64-bit pointer-size context. Other function prototypes need to refer to a 64-bit pointer when in a 32-bit pointer-size context.

HP C binds the pointer size used in a typedef at the time the typedef is made. Assuming this header file is compiled with no /POINTER_SIZE qualifier or with /POINTER_SIZE=SHORT, the typedef declaration of __char_ptr32 (1) is made in a 32-bit context. The typedef declaration of __char_ptr64 (2) is made in a 64-bit context.

#3

: 
#if __INITIAL_POINTER_SIZE 
#   if (__VMS_VER < 70000000) || !defined __ALPHA 
#      error " Pointer size usage not permitted before OpenVMS Alpha V7.0" 
#   endif 
#   pragma __pointer_size __save 
#   pragma __pointer_size 32 
#endif 
: 
(1)
: 
#if __INITIAL_POINTER_SIZE (2)
#   pragma __pointer_size 64 
#endif 
: 
(3)
: 
int abs (int __j); (4)
: 
__char_ptr32 strerror (int __errnum); (5)
: 
 
 
      

Before declaring function prototypes that support 64-bit pointers, the pointer context is changed (2) from 32-bit pointers to 64-bit pointers.

Functions restricted to 32-bit pointers are placed in the 32-bit pointer context section (1) of the header file. All other functions are placed in the 64-bit context section (3) of the header file.

Functions that have no pointer-size impact ((4) and (5)) are located in the 64-bit section. Functions that have no pointer-size impact except for a 32-bit address return value (5) are also in the 64-bit section, and use the 32-bit specific typedef s previously discussed.

#4

: 
#if __INITIAL_POINTER_SIZE 
#   pragma __pointer_size 64 
#endif 
: 
: 
#if __INITIAL_POINTER_SIZE == 32 (1)
#   pragma __pointer_size 32 
#endif 
: 
char *strcat (char *__s1, __const_char_ptr64 __s2); (2)
: 
#if __INITIAL_POINTER_SIZE 
#   pragma __pointer_size 32 
    : 
    char *_strcat32  (char *__s1, __const_char_ptr64 __s2); (3)
    : 
#   pragma __pointer_size 64 
    : 
    char *_strcat64  (char *__s1, const char *__s2); (4)
    : 
#endif 
: 
 
 
      

This example shows declarations of functions that have both a 32-bit and 64-bit implementation. These declarations are located in the 64-bit section of the header file.

The normal interface to the function (2) is declared using the pointer size specified on the /POINTER_SIZE qualifier. Because the header file is in 64-bit pointer context and because of the statements at (1), the declaration at (2) is made using the same pointer-size context as the /POINTER_SIZE qualifier.

The 32-bit specific interface (3) and the 64-bit specific interface (4) are declared in 32-bit and 64-bit pointer-size context, respectively.


Chapter 2
Understanding Input and Output

There are three types of input and output (I/O) in the HP C Run-Time Library (RTL): UNIX, Standard, and Terminal. Table 2-1 lists all the I/O functions and macros found in the HP C RTL. For more detailed information on each function and macro, see the Reference Section.

Table 2-1 I/O Functions and Macros
Function or Macro Description
UNIX I/O---Opening and Closing Files
close Closes the file associated with a file descriptor.
creat Creates a new file.
dup, dup2 Allocates a new descriptor that refers to a file specified by a file descriptor returned by open , creat , or pipe .
open Opens a file and positions it at its beginning.
UNIX I/O---Reading from Files
read Reads bytes from a file and places them in a buffer.
UNIX I/O---Writing to Files
write Writes a specified number of bytes from a buffer to a file.
UNIX I/O---Maneuvering in Files
lseek Positions a stream file to an arbitrary byte position and returns the new position as an int .
UNIX I/O---Additional X/Open I/O Functions and Macros
fstat, stat Accesses information about the file descriptor or the file specification.
flockfile, ftrylockfile, funlockfile File-pointer-locking functions.
fsync Writes to disk any buffered information for the specified file.
getname Returns the file specification associated with a file descriptor.
isapipe Returns 1 if the file descriptor is associated with a pipe and 0 if it is not.
isatty Returns 1 if the specified file descriptor is associated with a terminal and 0 if it is not.
lwait Waits for completion of pending asynchronous I/O.
ttyname Returns a pointer to the null-terminated name of the terminal device associated with file descriptor 0, the default input device.
Standard I/O---Opening and Closing Files
fclose Closes a function by flushing any buffers associated with the file control block, and freeing the file control block and buffers previously associated with the file pointer.
fdopen Associates a file pointer with a file descriptor returned by an open , creat , dup , dup2 , or pipe function.
fopen Opens a file by returning the address of a FILE structure.
freopen Substitutes the file, named by a file specification, for the open file addressed by a file pointer.
Standard I/O---Reading from Files
fgetc, getc, fgetwc, getw, getwc Returns characters from a specified file.
fgets, fgetws Reads a line from a specified file and stores the string in an argument.
fread Reads a specified number of items from a file.
fscanf, fwscanf, vfscanf, vfwscanf Performs formatted input from a specified file.
sscanf, swscanf, vsscanf, vswscanf Performs formatted input from a character string in memory.
ungetc, ungetwc Pushes back a character into the input stream and leaves the stream positioned before the character.
Standard I/O---Writing to Files
fprintf, fwprintf, vfprintf, vfwprintf Performs formatted output to a specified file.
fputc, putc, putw, putwc, fputwc Writes characters to a specified file.
fputs, fputws Writes a character string to a file without copying the string's null terminator.
fwrite Writes a specified number of items to a file.
sprintf, swprintf, vsprintf, vswprintf Performs formatted output to a string in memory.
Standard I/O---Maneuvering in Files
fflush Sends any buffered information for the specified file to RMS.
fgetpos Stores the current value of the file position indicator for the stream.
fsetpos Sets the file position indicator for the stream according to the value of the object pointed to.
fseek , fseeko Positions the file to the specified byte offset in the file.
ftell , ftello Returns the current byte offset to the specified stream file.
rewind Sets the file to its beginning.
Standard I/O---Additional Standard I/O Functions and Macros
access Checks a file to see whether a specified access mode is allowed.
clearerr Resets the error and end-of-file indications for a file.
feof Tests a file to see if the end-of-file has been reached.
ferror Returns a nonzero integer if an error has occurred while reading or writing a file.
fgetname Returns the file specification associated with a file pointer.
fileno Returns an integer file descriptor that identifies the specified file.
ftruncate Truncates a file at the specified position.
fwait Waits for completion of pending asynchcronous I/O.
fwide Sets the orientation a stream.
mktemp Creates a unique file name from a template.
remove, delete Deletes a file.
rename Gives a new name to an existing file.
setbuf, setvbuf Associates a buffer with an input or output file.
tmpfile Creates a temporary file that is opened for update.
tmpnam Creates a character string that can be used in place of the file-name argument in other function calls.
Terminal I/O---Reading from Files
getchar, getwchar Reads a single character from the standard input ( stdin ).
gets Reads a line from the standard input ( stdin ).
scanf, wscanf, vscanf, vwscanf Performs formatted input from the standard input.
Terminal I/O---Writing to Files
printf, wprintf, vprintf, vwprintf Performs formatted output to the standard output ( stdout ).
putchar, putwchar Writes a single character to the standard output and returns the character.
puts Writes a character string to the standard output followed by a new-line character.


Previous Next Contents Index