United States |
Previous | Contents | Index |
A few functions in the Compaq 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-6 shows the functions restricted to using 32-bit pointers. The Compaq C RTL offers no 64-bit support for these functions. You must ensure that only 32-bit pointers are used with these functions.
atexit | frexp | ioctl | sendmsg |
execv | getopt | modf | setbuf |
execve | iconv | putenv | setstate |
execvp | initstate | recvmsg | setvbuf |
Table 1-7 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.
decc$from_vms | decc$to_vms |
ftw | tputs |
This section introduces the pointer-size manipulations used in the Compaq 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.
#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 Compaq C compilers that support the /POINTER_SIZE qualifier predefine the macro __INITIAL_POINTER_SIZE . The Compaq 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".
DEC C Version 5.2 and higher is supported on many OpenVMS platforms. 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 Compaq 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.
Compaq C binds the pointer size used in a typedef at the time the typedef is made. 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.
There are three types of input and output (I/O) in the Compaq C Run-Time Library (RTL): UNIX, Standard, and Terminal. Table 2-1 lists all the I/O functions and macros found in the Compaq C RTL. For more detailed information on each function and macro, see the Reference Section.
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 Standard I/O Functions and Macros | |
fstat, stat | Accesses information about the file descriptor or the file specification. |
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 | Performs formatted input from a specified file. |
sscanf, swscanf | 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 | Positions the file to the specified byte offset in the file. |
ftell | 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 | 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. |
When you create a file using the Compaq C RTL I/O functions and macros, you can supply values for many RMS file attributes, including:
See the description of the creat function in the Reference Section for information on these values.
Other functions that allow you to set these values include open , fopen , and freopen .
For more information about RMS, see the Compaq C User's Guide for OpenVMS Systems.
2.2 UNIX I/O and Standard I/O
UNIX I/O functions are UNIX system services, now standardized by ISO POSIX-1 (the ISO Portable Operating System Interface).
UNIX I/O functions use file descriptors to access files. A file descriptor is an integer that identifies the file. A file descriptor is declared in the following way, where file_desc is the name of the file descriptor:
int file_desc; |
UNIX I/O functions, such as creat , associate the file descriptor with a file. Consider the following example:
file_desc1 = creat("INFILE.DAT", 0, "rat=cr", "rfm=var"); |
This statement creates the file, INFILE.DAT, with file access mode 0, carriage-return control, variable-length records, and it associates the variable file_desc1 with the file. When the file is accessed for other operations, such as reading or writing, the file descriptor is used to refer to the file. For example:
write(file_desc1, buffer, sizeof(buffer)); |
This statement writes the contents of the buffer to INFILE.DAT.
There may be circumstances when you should use UNIX I/O functions and macros instead of the Standard I/O functions and macros. For a detailed discussion of both forms of I/O and how they manipulate the RMS file formats, see Chapter 1.
Standard I/O functions are specified by the ANSI C Standard.
Standard I/O functions add buffering to the features of UNIX I/O and use file pointers to access files. A file pointer is an object of type FILE * , which is a typedef defined in the <stdio.h> header file as follows:
typedef struct _iobuf *FILE; |
The _iobuf identifier is also defined in <stdio.h> .
To declare a file pointer, use the following:
FILE *file_ptr; |
You use the Standard I/O fopen function to create or open an existing file. For example:
#include <stdio.h> main() { FILE *outfile; outfile = fopen("DISKFILE.DAT", "w+"); . . . } |
Here, the file DISKFILE.DAT is opened for write-update access.
The Compaq C RTL provides the following functions for converting between file descriptors and file pointers:
Previous | Next | Contents | Index |
|