United States |
Previous | Contents |
This section lists features that are considered obsolete in the
Compaq C RTL; they are retained for VAX C RTL
compatibility only and should not be used for any new development.
1.3.3.1 VAXC$MALLOC_OPT and Related Routines
The following routines are considered obsolete in the Compaq C RTL. The Compaq C RTL versions of the standard C memory allocation routines are faster and more efficient than the VAX C RTL versions.
The global symbols sys_nerr and sys_errlist are obsolete in the
Compaq C RTL. They are provided for VAX C RTL
compatibility only; new error messages have not been added for a number
of releases of the VAX C RTL. The symbols are still provided in
the
<perror.h>
header file. Programmers are advised to use the portable ANSI C
functions
perror
or
strerror
instead.
1.3.4 Debugging and the Compaq C RTL Object Library
The Compaq C RTL object library contains a LIB$INITIALIZE psect contribution. When debugging programs linked against the Compaq C RTL versions of the object libraries, you must enter GO to reach the main program, and error tracebacks will have an additional call stack listed. For example:
$ CC/DECC/DEBUG/NOOPTIMIZE HELLOWORLD $ LINK/DEBUG HELLOWORLD,SYS$LIBRARY:DECCRTL/LIBRARY $ RUN HELLOWORLD VAX DEBUG Version V6.0DS-004 %DEBUG-I-INITIAL, language is C, module set to HELLOWORLD %DEBUG-I-NOTATMAIN, type GO to get to start of main program DBG> GO break at routine HELLOWORLD\main 425: main() DBG> GO Hello world! %DEBUG-I-EXITSTATUS, is '%SYSTEM-S-NORMAL, normal successful completion' DBG> EXIT $ |
This section documents interoperability restrictions that apply when multiple copies of the C RTL are used in the same process (or in spawned processes) as part of running an application.
Most applications are expected to work correctly with any mix of C RTLs in the same process. However, any shareable image that exchanges part of the C RTL context with its caller could lead to problems in an image that uses two or more C RTLs (see Section 1.4.1). Also, there can be link conflicts when building an application that uses multiple C RTLs (see Section 1.4.2). Finally, you must be sure to avoid version mismatches of RTL components when distributing certain Compaq or user-written applications to other systems (see Section 1.4.3).
The following are examples of mixed C RTL use:
Most applications are expected to work correctly with any mix of C RTLs in the same process. However, any shareable image that exchanges part of the C RTL context with its caller could lead to problems in an image that uses two C RTLs. Furthermore, these problems can occur in an indeterminate way.
The term C RTL context refers to the program state information that is maintained by the C RTL to implement C language semantics. Generally, this is information that applies to the program as a whole, not to one specific subroutine. An example of C RTL context is the file descriptor table. File descriptors are a C language concept maintained by the C RTL. Application variables and the process priority are examples of what is not part of C RTL context. The first is part of the application context. The second is part of the OpenVMS context.
A program that exports C RTL context is said to be unencapsulated; one that does not export C RTL context is said to be encapsulated.
An exporter of C RTL context is likely to be a programming library, but any program consisting of multiple shareable images might also pass C RTL context between images.
Exporting C RTL context between two instances of C RTLs generally will not work. A shareable image that needs to pass C RTL context to its caller must ensure that the caller will be built with the same copy of a C RTL as the shareable image. C RTL context can never be passed between a C RTL object library and a C RTL shareable image, even if they are instances of the same C RTL.
The following is a complete list of the data structures and information that comprise the C RTL context:
There are some general solutions to these restrictions. The provider of a subsystem has a couple of options:
For users of an unencapsulated subsystem, one option is to carefully use #define preprocessor macros to map appropriate VAX C RTL routine calls into Compaq C routine calls without mapping all of them (see Section 1.4.1.1).
The following list gives some instances of exporting C RTL context. The term subsystem refers to a shareable image that provides a set of routines to be called by the caller, which is typically a main program, or possibly another shareable image. If any of these instances occur in an application where a subsystem is linked with one C RTL, and the caller of that subsystem is linked with a different C RTL, then the application may not function correctly.
In general, it is a good idea for subsystems to not export C RTL context. If a subsystem used by an application does export C RTL context, the only solution that insures that the application will run correctly is for the subsystem and the caller to use the same copy of that C RTL. For example, if the subsystem is linked with VAXCRTL.EXE, then the caller must also be linked with VAXCRTL.EXE. If the subsystem is linked with DECC$SHR.EXE, then the caller must also be linked with DECC$SHR.EXE. Note that any shareable image that does not export C RTL context will continue to function correctly with whatever version of the C RTL it is currently using.
The following sections describe solutions to the unencapsulated problem.
1.4.1.1 Becoming Encapsulated---Solutions to the General Problem
There are several options available for changing an unencapsulated image into an encapsulated one:
$ create my_api_memory.c void free_for_XYZ (void *p) { free (p); return; } $ CC/VAXC my_api_memory.c $ LINK/MAP/FULL/CROSS myapp, my_api_memory, SYS$INPUT/OPT SYS$SHARE:VAXCRTL/SHARE |
#define free_for_XYZ decc$free |
If a subsystem returns C file descriptors or file pointers, the application and subsystem must both use the same C RTL. You can use the previous general techniques to encapsulate an unencapsulated subsystem.
For the case of
stdin
,
stdout
, and
stderr
, each instance of the C RTL has its own channel open to these files.
The resulting behavior is line-at-a-time processing of input or output.
This is much the same as if the application mixed C standard I/O with
the standard input or output channels of a different programming
language.
1.4.1.3 Considerations for errno
The Compaq C RTL is dependent on a new image, SYS$LIBRARY:CMA$TIS_SHR.EXE, to provide errno support. If you implement a run-time library that modifies errno to communicate error status to callers, do not modify errno directly. If you do, the modified errno will not be communicated to all C RTLs in the process. For example, if a shareable image that modifies errno is linked with the Compaq C RTL, and the main program is linked with the VAX C RTL, the main program will never see the modified errno value from the shareable image.
The recommended way to modify errno is to call the function cma$tis_set_errno_value . This function has the following prototype:
void cma$tis_errno_set_value(int value); |
For example, consider an image that needs to modify errno and has code similar to the following:
if (error_situation) { errno=ERROR_CODE; return(error_status); } |
To correctly modify errno , change this code to the following:
if (error_situation) { void cma$tis_errno_set_value(int); cma$tis_errno_set_value(ERROR_CODE); return(error_status); } |
Note that programs that merely examine the value of
errno
are not affected by this implementation change.
1.4.1.4 Child Process Context
When spawning a child process using vfork , the main routine in the child uses a C RTL routine to inherit some context from the parent. This context is documented in the Compaq C RTL Reference Manual for OpenVMS Systems, and includes the list of open file descriptors, among other things. The restrictions on mixed C RTL context between different instances of the C RTL applies here as well.
Because of changes in the implementation of forking, both the parent and child process must use the same C RTL to communicate the C RTL context, as shown in the following figure:
The C RTL context passed from the parent is limited to the context visible from the exec routine called. Therefore, if the Compaq C RTL exec routine is called, only files opened in the Compaq C RTL are passed to the child process.
In the child process, the C RTL routine called by main re-establishes the context that gets used. Therefore, if main is using the Compaq C RTL, the inherited file descriptors are reopened by the Compaq C RTL. These file descriptors are not visible to the VAX C RTL.
A related problem is context between
vfork
and
exec
. The
vfork
routine establishes some context that gets used by the
exec
routines. While this context is implicitly passed (rather than
explicitly by the application), it has the same restriction as other
mixed C RTL context. The version of
vfork
must match the version of
exec
(that is, a Compaq C RTL version of
vfork
must match the Compaq C RTL version of
exec
).
1.4.1.5 Random Number Seed
Each C RTL linked into the application will have its own random number
seed. The effect is that each C RTL will have the exact same
pseudo-random sequence. If the application intends to call
srand
to set the random number seed, each seed must be updated.
1.4.1.6 Signal Context
The C RTL internally maintains some context to describe signal handlers
that have been enabled. With multiple instances of the C RTL in one
process, there can be multiple signal handlers enabled for the same
signal. For software signals, the signal handler used is the one that
matches the section of the application that raises the signal. For
signals caused by hardware exceptions (such as reserved operand faults,
or access violations), the signal handler used depends on active call
frames. Calls to
setjmp
establish a C RTL condition handler for the frame. The
main
program always has a C RTL condition handler enabled. The most recent
frame that has a C RTL condition handler established will catch the
hardware exception. If this C RTL condition handler is for
Compaq C, it looks for a signal handler established with a
Compaq C RTL
signal
or
sigvec
routine. If the condition handler is for VAX C, then the signal
handler established with the VAX C RTL gets invoked.
1.4.1.7 VAXC$CRTL_INIT and Context Initialization for main Program
As mentioned previously, some C RTL context initialization occurs when the main program starts and whenever the vaxc$crtl_init routine is called. This initialization includes establishing a VAX condition handler to handle hardware exceptions, inheriting context from the parent process if this is a child process, establishing a Ctrl/C handler, setting the default umask , and setting up environment variables accessible through the global object environ .
When multiple C RTLs are used in one application, only one set of context is initialized by default. To get the other C RTL context initialized, you must make an explicit call to the other version of vaxc$crtl_init . If, for example, a main program that is linked with the VAX C RTL calls a subroutine that is linked with the Compaq C RTL, the subroutine must contain an explicit call to vaxc$crtl_init to initialize the correct RTL context (Compaq C RTL, in this case) for later access.
Previous | Next | Contents |
|