United States    
COMPAQ
Compaq C

Compaq C
Migration Guide for OpenVMS VAX Systems


Previous Contents

1.3.3 Compaq C RTL Obsolete Features

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.

1.3.3.2 sys_nerr and sys_nerrlist Global Symbols

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
$ 

1.4 C RTL Interoperability Concerns

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:

1.4.1 Problems with Images that Export C RTL Context

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:

1.4.1.2 Issues for File I/O

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
  

1.800.AT.COMPAQ

privacy and legal statement