Updated: 21 April 1999 |
Compaq C++
|
Previous | Contents | Index |
The template instantiation model has been completely redesigned for Version 6.0. The changes include:
A C++ template is a framework for defining a set of classes or functions. The process of instantiation creates a particular class or function of the set by resolving the C++ template with a group of arguments that are themselves types or values. For example:
template <class T> class Array { T *data; int size; public: T &operator[](int); /* ...*/ }; |
The code in this example declares a C++ class template named Array that has two data members named data and size and one subscript operator member function. Array<int> instantiates Array with type int. This instantiation generates the following class definition:
class Array { int *data; int size; public: int &operator[](int); /* ...*/ }; |
The compiler supports instantiation of C++ class, function, and static
data member templates. The following sections describe the alternative
methods available for instantiating templates: automatic or manual
instantiation.
5.2 Automatic Template Instantiation
In automatic template instantiation mode, the compiler attempts to instantiate every referenced template at compile time. For automatic instantiation to work, at least one compilation that references a template function must be able to find the template definition. There is no restriction on where a template can be declared or defined, as long as the definition is visible to the compilation unit. You can use implicit inclusion to find it.
The compiler writes instantiation object files to a directory called
the repository; file names are based on the names of the entities being
instantiated. The default repository is [.cxx_repository].
5.2.1 Specifying Alternate Repositories
You can use the /repository command-line option to specify one or more alternate repository directories. There is one object file in the repository for each instantiated template function, for each instantiated static data member, and for each virtual table required for virtual functions.
When the program is linked, the linker searches the repositories for
needed template instantiations.
5.2.2 Reducing Compilation Time with the /template_define=timestamp Option
To keep instantiations up to date, the compiler always instantiates templates by default, even if the required template already exists in the respository. However, in environments that share many templates among many sources, this process can increase compilation time.
In these environments, users can specify the /template_define=timestamp option to override the default behavior and thereby reduce compilation time. This option causes the compiler to create a timestamp file named TIMESTAMP. in the repository. Thereafter, instantiations are added or regenerated only if needed; that is, if they do not alreay exist, or if existing ones are older than the timestamp.
The /template_define=timestamp option is immediately useful when building a system from scratch, starting with an empty repository. It avoids reinstantiating unchanged code and is totally safe, because all required instantiations are generated and up to date.
Incremental application building is normally done without this option, so that new instantiations overwrite earlier ones as sources are recompiled.
Although the /template_define=timestamp option is intended mainly for initial builds, you can use it for ongoing development in a structured way. Because the compiler creates a new timestamp file only if one does not already exist, you must remove or modify any existing timestamp file before making changes to your code base. This procedure ensures that all subsequent compilations generate up-to-date instantiations.
In the following example, the file is removed before and immediately after the compilation of a.cxx, b.cxx, and c.cxx.
delete [.cxx_repository]TIMESTAMP.;* cxx /template_define=timestamp a.cxx cxx /template_define=timestamp b.cxx cxx /template_define=timestamp c.cxx delete [.cxx_repository]TIMESTAMP.;* |
All instantiations needed by a.cxx, b.cxx, and a.cxx are generated only once, as opposed to the default scheme, in which they would be generated three times if all three modules used the instantiations.
Specifying the /template_define=verbose
option causes the compiler to emit an informational message naming the
instantiation and repository file being skipped in this mode.
When implicit inclusion is enabled, the compiler assumes that if it
needs a definition to instantiate a template entity declared in a .h or .hxx file,
it can implicitly include the corresponding implementation file to
obtain the source code for the definition. For example, if a template
entity ABC::f is declared in file xyz.h, and an instantiation of ABC::f is required in a compilation but no
definition of ABC::f appears in the
source code, the compiler checks whether a file xyz.cxx exists. If it does, the compiler
processes it as if it were included at the end of the main source file.
When looking for a template definition, the compiler uses the following
lookup order:
For source files, the appropriate suffixes are, in order of preference:
.CXX, .C,
.CC, and .CPP or as defined by the /template_define=definition_file_type qualifier.
The compiler ignores any file extension that does not begin with a dot
(.).
The /template_define=definition_file_type
qualifier allows the user to define explicitly the file extensions to
be used with implicit inclusion. For example:
5.2.3 Implicit Inclusion
cxx file.cxx /template_define=def=".CPP.CC" |
This command searches for template definition files with the extensions
.CPP and .CC.
In general, the use of automatic template instantiation is transparent
to the user. Automatic template instantiation is enabled by default.
The following commands are equivalent:
5.2.4 Compiling Programs with Automatic Instantiation
cxx file.cxx cxx/template_define=(auto,pragma) file.cxx cxx/repository=[.cxx_repository] file.cxx |
These commands:
You can specify the repository explicitly with the /repository switch. For example:
cxx /repository=c$:[project.repository] file.cxx |
This command compiles file.cxx, produces an object file in the current directory, and puts instantiated template files in the directory C$:[project.repository].
You can specify multiple directories using the /repository option. The first named repository is denoted as the read/write repository. The compiler writes instantiation files to this repository. The other repositories are denoted as read only repositories. They are searched by the link command as described in Section 5.2.5.
The compiler attempts to instantiate templates at compile time; therefore, any specialization used in the program must be declared in each file in which the specialization is referenced, to prevent the instantiation of the overridden template function.
If a template instantiation refers to a static function, that function is created as an external entry point in the primary object file, and the instantiation object file in the repository then refers to this __STF function.
If the template instantiation is linked into an application that does
not have the original primary object file, an unresolved reference to
the __STF function occurs. If this
happens, recompile an object file that regenerates the instantiation or
use manual instantiation to reinstantiate the template.
5.2.5 Linking Programs with Automatic Instantiation
When compiling and linking an application, you must use the same repositories in both the compilation and link steps.
If you name a repository explicitly in the compile step, you must also name it in the link step. For example:
cxx /repository=[.my_repository] a.cxx,b.cxx cxxlink /repository=[.my_repository] a.obj b.obj |
If you use different repositories the compilation of the sources, you must specify all of them on the link step:
cxx /repository=[.repository1] a.cxx cxx /repository=[.repository2] b.cxx cxxlink /repository=([.repository1],[.repository2]) a.obj b.obj |
At link time, the specified repositories are searched in the order given, to find the required instantiations. If you use several repositories, and if one of them is the default, you must specify all repositories on the link step:
cxx a.cxx cxx /repository=[.repository2] b.cxx cxx /repository=([.cxx_repository],[.repository2]) a.obj b.obj |
It is usually much easier and safer to use a single repository, because the same instantiations could potentially be present in multiple repositories, and it is possible to update some but not all repositories when changes are made to templates.
The cxxlink step processes object files so that all the external symbol references are resolved. The objects are linked together in the following order:
Note the following:
The compiler provides the following methods to instantiate templates manually:
The next sections describe the following instantitation directives:
The compiler provides a mechanism for manual instantiation, using the
#pragma define_template directive. This
directive lets you tell the compiler what class or function template to
instantiate in conjunction with the actual arguments with which the
template is to be instantiated. The #pragma
define_template directive has the following format:
#pragma define_template identifier
<template_arguments>
Identifier is the name of the class or function template that the compiler is directed to instantiate at compile time. For the instantiation to succeed, the definition of the template must appear before the #pragma define_template directive.
Template_arguments is a list of one or more actual types that correspond to the template parameters for the particular class or function template being instantiated. Whatever type is specified is used as the type for the instantiation.
The following is an example of a valid template manual instantiation:
//main.cxx #include <stdlib.h> template <class T> void sort (T*); int al[100]; float a2[100]; int main() { sort(a1); sort(a2); return EXIT_SUCCESS; } //sort.cxx template <class T> void sort (T *array) { /* body of sort */ } #pragma define_template sort<int> #pragma define_template sort<float> |
To compile and link these sources, enter the following command:
cxxlink main.cxx,sort.cxx /template_define=(noauto) |
When you use #pragma define_template or explicit instantiation, only the specified template is instantiated; templates to which it refers because of member types or base classes are not instantiated.
Sorting an array of template class elements requires the use of additional pragmas for the module sort.cxx. For example:
template <class T> void sort (T* array) { /*body of sort*/ } template <class T> class entity { public: T member; int operator < (const entity<T> &) const; } template <class T> int entity<T>::operator < (const entity<T> &operand) const { return member < operand.member; } int al[100]; float a2[100]; entity<int> a3[100]; #pragma define_template sort<int> #pragma define_template sort<float> #pragma define_template sort<entity<int> > void sort_all_arrays () { sort(a1); sort(a2); sort(a3); } |
The define_template pragma is position sensitive. If a define_template occurs lexically before a function, member function, or static data member template definition, the compiler is unable to instantiate the corresponding template because the body of that template is not present before the pragma directive.
The compiler instantiates all instances of sort and of entity::operator < needed for this compilation unit.
To organize a program to use the define_template pragma, you can place the declarations of class and functions templates into header files, and instantiate all instances of a particular template from a single compilation unit. The following example shows how to do this:
// sort.h #include <stdlib.h> template <class T> void sort (T*); // entity.h template <class T> class entity { public: T member; int operator < (const entity<T> &) const; }; // main.cxx #include "sort.h" #include "entity.h" int al[100]; float a2[100]; entity<int> a3[100]; int main() { sort(a1); sort(a2); sort(a3); return EXIT_SUCCESS; } // sort.cxx #include "sort.h" #include "entity.h" template <class T> void sort (T* array) { /*body of sort*/ } #pragma define_template sort<int> #pragma define_template sort<float> #pragma define_template sort<entity<int> > |
Compiling the following file provides a definition of entity::operator < with type int:
// entity.cxx #include "entity.h" template <class T> int entity<T>::operator < (const entity<T> &operand) const { return member < operand.member; } #pragma define_template entity<int> |
To compile this example, issue the following command:
cxxlink main.cxx,main.obj,sort.cxx,sort.obj,entity.cxx,entity.obj |
If the program uses other instantiations of entity in other compilation units, you can provide definitions of operator < for those entities by adding define_template pragmas to entity.cxx. For example, if other compilation units use the following instantiations of entity, appending the following pragmas to entity.cxx causes the compiler to generate instantiations of operator < for those requests of entity:
entity<long> and entity< entity<int> >, #pragma define_template entity<long> #pragma define_template entity< entity<int> > |
Like any other pragma, the #pragma
define_template pragma must appear on a single line.
Pragmas may be continued on multiple lines by escaping the end of line
with a backslash ( \ ) as with other preprocessor statements.
5.3.1.2 #pragma instantiate and #pragma do_not_instantiate
The compiler also provides several pragmas that provide fine control over the instantiation process. Instantiation pragmas, for example, can be used to control the instantiation of specific template entities or sets of template entities. There are two instantiation pragmas:
The argument to the instantiation pragma can be:
a template class name | A<int> |
a template class declaration | class A<int> |
a member function name | A<int>::f |
a static data member name | A<int>::i |
a static data declaration | A<int>::i |
a member function declaration | void A<int>::f(int, char) |
a template function declaration | char* f(int, float) |
A pragma in which the argument is a template class name (for example, A<int> or class A<int> is equivalent to repeating the pragma for each member function and static data member declared in the class. When instantiating an entire class, a given member function or static data member may be excluded using the do_not_instantiate pragma. For example:
#pragma instantiate A<int> #pragma do_not_instantiate A<int>::f |
The template definition of a template entity must be present in the compilation for an instantiation to occur. If an instantiation is explicitly requested by use of the instantiate pragma and no template definition is available or a specific definition is provided, an error is issued.
template <class T> void f1(T); // No body provided template <class T> void g1(T); // No body provided void f1(int) {} // Specific definition #include <stdlib.h> int main() { int i; double d; f1(i); f1(d); g1(i); g1(d); return EXIT_SUCCESS; } #pragma instantiate void f1(int) // error - specific definition #pragma instantiate void g1(int) // error - no body provided |
The functions f1(double) and g1(double) are not instantiated (because no bodies were supplied) but no errors are produced during the compilation (if no bodies are supplied at link time, a linker error is produced).
A member function name (for example, A<int>::f can be used as a pragma argument only if it refers to a single user-defined member function (that is, not an overloaded function). Compiler-generated functions are not considered, so a name may refer to a user-defined constructor even if a compiler-generated copy constructor of the same name exists. Overloaded member functions can be instantiated by providing the complete member function declaration:
#pragma instantiate char* A<int>::f(int, char*) |
The argument to an instantiation pragma must not be a
compiler-generated function, an inline function, or a pure virtual
function.
5.3.2 Using Command Qualifiers for Manual Instantiation
Alternatively, you could use the /template_define qualifier to instantiate templates manually.
Considering the previous examples in this section, you can use this qualifier to supply definitions of sort<int>, sort<float>, and sort<entity><int> by compiling the following file using /template_define:
// sort.cxx #include "sort.h" #include "entity.h" template <class T> static sort (T* array) { /*body of sort*/ } static void function_never_used () { int al[100]; float a2[100]; entity<int> a3[100]; sort(a1); sort(a2); sort(a3); } |
You can use the /template_define=used and /template_define=local qualifiers for manual template instantiation. The /template_define=used qualifier acts like /template_define, except that only those template instantiations that are referenced in the source file are actually instantiated. The /template_define=local qualifier acts like /template_define=used, except that the templates are instantiated with internal linkage. This provides a simple way to build applications but creates executables that are larger than necessary. It also fails if the template classes being instantiated have static data members.
You can use the /template_define=all_repository, /template_define=used_repository, and /template_define=implicit_local qualifiers to
create preinstantiation libraries. See Section 5.5.
The following sections discuss templates in the context of advanced
program development.
The compiler does no dependency management of its own. Because template
instantiations are compiled when source files that reference those
instantiations are compiled, those source files must be recompiled if
the template declaration or definition changes.
The /MMS output from the compiler lists
the implicitly included files, so that the MMS program can automatically recompile any
source files that depend upon template files. If MMS is not being used, it is the user's
responsibility to ensure that instantiations that have changed are
recompiled. The user does so by recompiling at least one source file
that references the changed instantiations.
The compiler does not check command line dependencies of template
instantiations at link time. If you compile two different source files
that instantiate a specific template with two different sets of
options, the last option setting affects the template instantiation.
Use consistent option settings for each build into each repository.
Examples of options settings that could cause unexpected results are as
follows:
5.4 Advanced Program Development and Templates
5.4.1 Dependency Management
5.4.2 Mixing Automatic and Manual Instantiation
Object files that have been compiled using manual instantiation can be linked freely with objects that have been compiled using automatic instantiation. To ensure that the template instantiations needed by the files compiled with automatic instantiation are provided, the application must be linked using automatic instantiation, and the appropriate repositories must be present.
When a template instantiation is present in an explicitly named object
file or object library it takes precedence over the same named
instantiation in a repository.
Creating libraries with object files created with automatic
instantiations is relatively straightforward. You must decide where the
instantiations that were generated automatically are provided to the
users of the library. For applications that use the library to link
successfully, all template instantiations that are needed by the code
in the library must be available at link time. This can be done in two
ways:
It is usually easiest to put the instantiations in the library. This is
a good choice if the instantiations are internal to the library and are
not instantiated directly by the user's code. To put the instantiations
in the library, add all of the object files in the repositories
required by the library into the library as shown in the following
example:
5.4.3 Creating Libraries
cxx /repository=[.lib_repository] a.cxx,b.cxx,c.cxx library/create/object mylib library/insert/object mylib a.obj,b.obj,c.obj library/insert/object mylib [.lib_repository]*.obj |
If the template instantiations can be overridden by the user, the templates should be provided in a repository that the user specifies after all the user's repositories. For the previous example, create the library as follows:
cxx /repository=[.lib_repository] a.cxx,b.cxx,c.cxx library/create/object mylib library/insert/object mylib a.obj,b.obj,c.obj |
When linking the application, enter the cxxlink command as follows:
cxxlink user_code.obj,mylib/lib |
If some objects from [.lib_repository] are not contained in mylib.olb, specify [.lib_repository] as the last read-only repository on the line follows:
cxxlink /repository=([.cxx_repository],[.lib_repository]) user_code.obj,mylib/lib |
You must explicitly name the repository when linking, even if it is the default repository [.cxx_repository]; cxx first satisfies all unresolved instantiations from [.cxx_repository], and uses [.lib_repository] to resolve any remaining unresolved instantiations.
Only the instantiations that are required by the code in the library
are generated in the library repository lib_repository. If you must provide other
instantiations that you require but cannot instantiate, you must
provide these instantiations using manual template instantiation or by
specifying the qualifier /template_define=all_repository.
Because the automatic instantiation model has changed to a compile time
model with Version 6.0, (see Sections 5.2.4 and 5.2.5),
the procedure used to create a common instantiation library has also
changed. This section describes the new procedure.
If you want to put all current instantiations into a common
instantiation library, follow these steps:
The following examples show how to create a common instantiation
library for all the instantiations currently being automatically
instantiated for this file.
5.4.4 Creating a Common Instantiation Library
// foo.cxx #include <stdlib.h> #include <vector> #include "C.h" int main() { vector<C> v; v.resize(20); return EXIT_SUCCESS: } // C.h #ifndef __C_H class C {}; #endif |
Compiling with the /TEMPLATE=VERBOSE qualifier shows which instantiations occur automatically:
void vector<T,Allocator>::resize (size_type new_size) ..........................^ %CXX-I-INSTENTITY, automatically instantiating void std::vector<C, std::allocator<C > >::resize(unsigned int) at line number 90 in module VECTOR.CC of text library SYS$COMMON:[SYSLIB]CXXL$ANSI_DEF.TLB;4 // |
// inst.cxx #include <vector> #include "C.h" #pragma instantiate void std::vector<C, std::allocator<C > >::resize(unsigned long) #pragma instantiate void std::vector<C, std::allocator<C > >::insert(C *, unsigned long, const C &) #pragma instantiate void std::vector<C, std::allocator<C > >::__insert(C *, unsigned long, const C &, __true_category) #pragma instantiate C *std::copy_backward(C *, C *, C *) #pragma instantiate void std::fill(C *, C *, const C &) #pragma instantiate C *std::copy(C *, C *, C *) #pragma instantiate const unsigned long std::basic_string<char, std::char_traits<char >, std::allocator<void> >::npos |
#ifndef __C_H class C {}; #include <vector> #ifndef __BUILDING_INSTANTIATIONS #pragma do_not_instantiate void std::vector<C, std::allocator<C > >::resize(unsigned long) #pragma do_not_instantiate void std::vector<C, std::allocator<C > >::insert(C *, unsigned long, const C &) #pragma do_not_instantiate void std::vector<C, std::allocator<C > >::__insert(C *, unsigned long, const C &, __true_category) #pragma do_not_instantiate C *std::copy_backward(C *, C *, C *) #pragma do_not_instantiate void std::fill(C *, C *, const C &) #pragma do_not_instantiate C *std::copy(C *, C *, C *) #pragma do_not_instantiate const unsigned long std::basic_string<char, std::char_traits<char >, std::allocator<void> >::npos #endif #endif |
cxx/DEFINE=BUILDING_INSTANTIATIONS inst.cxx |
cxx foo.cxx cxxlink foo inst |
To verify that your procedure worked correctly, you can remove the cxx_repository subdirectory before you compile foo.cxx. This subdirectory should contain no instantiations after linking with the inst object file.
If you have an inst.cxx file that
contains many instantiations and you do not want all the symbols in the
inst object file to be put into a user's
executable even if only some symbols are used, (as happens with archive
libraries), you can either split the inst.cxx into many smaller source files, or
specify the /define_template=used_repository qualifier to
create the instantiations as separate object files in the repository
(see Section 5.6). You must then link all the individual object files
in the repository into your library.
As shown in Section 5.4.4, multiple repositories can be specified to
link an application. The first repository named is the read-write
repository, and when compiling, the compiler writes instantiation
object files into it. At link time, all repositories are read only.
The repositories are searched in a linear order, iteratively, and
satisfy only the unresolved instantiations from each pass. That is,
references from instantiations that are added in one pass are not
resolved until the next pass. Consider the link line in the previous
example:
5.4.5 Multiple Repositories
mylib.olb |
In this example, all references that could be resolved from lib_repository would be resolved. Any reference
arising from an instantiation in lib_repository would be resolved by
instantiations in [.cxx_repository].
The following cxx command-line options
are specific to the instantiation of templates:
The /template_define=local qualifier
cannot be used in conjunction with automatic template instantiation. If
automatic instantiation is enabled by default, it is disabled by the
/template_define=local option. Explicit
use of /template_define=local and /pt is an error.
5.5 Command-Line Qualifiers for Template Instantiation
/template_define
Instantiate all template entities declared or referenced in the
compilation unit, including typedefs. For each fully instantiated
template class, all its member functions and static data members are
instantiated even if they were not used. Nonmember template functions
are instantiated even if the only reference was a declaration.
Instantiations are created with external linkage. Overrides /repository at compile time. Instantiations are
placed in the user's object file.
/template_define=all/template_define=[no]automatic
Directs the compiler to turn on or off automatic instantiation of C++
templates. The default is /TEMPLATE_DEFINE=AUTOMATIC.
/template_define=all_repository
Instantiate all templates declared or used in the source program and
put the object code generated as separate object files in the
repository. Instantiations caused by manual instantiation directives
are also put in the repository. This is similar to /template_define=all except that explicit
instantiations are also put in the repository, rather than than an
external symbol being put in the main object file. This option is
useful for creating a pre-instantiation library.
/template_define=definition_file_type="file-type-list"
Specifies a string that contains a list of file types that are valid
for template definition files. Items in the list must be separated by
commas and preceded by a period. A type is not allowed to exceed the
OpenVMS limit of 31 characters. This option is applicable only when
automatic instantiation has been specified. The default is
/TEMPLATE_DEFINE=DEF=".CXX,.C,.CC,.CPP".
/template_define=implicit_local
Generate explicit template instantiations as external symbols in the
user's object file, but generate any template instantiations that are
used with internal linkage. Similar to /template_define=local, except that manual
instantiations in the source file are linked externally. This is useful
for build systems that require explicit control of the template
instantiation mechanism. Implicitly generated template instantiations
with internal linkage can produce larger object files.
/template_define=local
Similar to /template_define=used except
that the functions are given internal linkage. This option provides a
simple mechanism for getting started with templates. The compiler
instantiates as local functions the functions used in each compilation
unit, and the program links and runs correctly (barring problems
resulting from multiple copies of local static variables). However,
because many copies of the instantiated functions can be generated,
this option might not be not suitable for production use.
/template_define=pragma
Determines whether the compiler ignores #pragma
define_template directives encountered during the
compilation. This option lets you quickly switch to automatic
instantiation without having to remove all the pragma directives from
your program's code base.The default is /TEMPLATE_DEFINE=PRAGMA, which
enables #pragma define_template.
/template_define=used
Instantiate those template entities that were used in the compilation.
This includes all static data members for which there are template
definitions. Overrides /pt at compile
time.
/template_define=used_repository
Like /template_define=all_repository, but
instantiates only templates used by the compilation. The explicit
instantiations are also put into the repository as separate object
files.
/template_define=verbose
Turns on verbose or verify mode to display each phase of instantiation
as it occurs. During the compilation phase, informational level
diagnostics are generated to indicate which templates are automatically
being instantiated. This option is useful as a debugging aid.
/template_define=timestamp
Causes the compiler to create a timestamp file named TIMESTAMP. in the repository. Thereafter,
instantiations are added or regenerated only if needed; that is, if
they do not alreay exist, or if existing ones are older than the
timestamp.
5.6 Compatibility with Earlier Versions of the Compiler
The automatic template instantiation model is new with Version 6.0, and is not directly compatible with previous template instantiation mechanisms. When linking applications using Version 6.0 and later, instantiations might not be resolved from existing Version 5.n repositories. Where possible, it is safest to start fresh with an empty repository and create the required instantiations by compiling all source files. If this is not possible, there are some strategies that can be used to link mixed generation instantiations.
If you used both Version 6.n and Version 5.n to build
applications, Compaq strongly recommends that you use different
repositories to contain automatic template instantiations for Version
6.n and Version 5.n compilations. The default
repository name is the same for Version 6.n as for prior
versions. Thus, if you use Version 6.n with older
pre-6.n versions, you should do compilations in a different
directory for each compiler or explicitly specify a different
repository for each using the /repository
qualifier.
When linking applications using Version 6.n against
instantiations created with Version 5.n, it is necessary to
complete the Version 5.n instantiation process, to create
instantiation object files. If old_repository is a Version 5.n
repository then you would create the Version 5.n instantiation
object files by using the Version 5.n cxxlink:
5.6.1 Linking with Version 5.n Instantiations
cxxlink/noexe /repository=[.old_repository] <Version 5.n object files> |
<Version 5.n object files> are the object files that were created using the Version 5.n compiler; old_repository now contains the instantiation object files. Create a library of these object files as follows:
library/create/object lib_old_repository/log library/insert/object lib_old_repository/log [old_repository]*.obj |
When linking using Version 6.n, specify lib_old_repository.olb after all of the Version
5.n object files that are being linked.
In a similar way, you can create a library of Version 6.n
instantiation object files to link into a Version 5.n
application being linked using C++ Version 5.n. If new_repository is the Version 6.n
repository, then a library of the instantiations would be created by:
5.6.2 Linking Version 5.n Applications Against Version 6.n Repositories
library/create/object lib_new_repository/log library/insert/object lib_new_repository/log [new_repository]*.obj |
When linking using Version 5.n, specify lib_new_repository.olb after all of the Version 6.n object files that are being linked.
Previous | Next | Contents | Index |
Legal |