The C/C++ compiler supports automatic instantiation (INSTANTIATION=*AUTO) by default in the language modes C++ V3, C++ 2017 and C++ 2020. This enables you to compile source code and link the generated objects without being concerned about any required instantiations.
Note that the discussion which follows refers to the automatic instantiation of template entities for which there is no explicit instantiation request (template
declaration) and no instantiate
pragma.
Requirements
For each instantiation, the compiler expects a source file that contains both a reference to the required instantiation and the definition of the template entity as well as all types required for the instantiation of that template entity. The latter two requirements can be satisfied by the following methods:
Each
.h
file that declares a template entity also contains either the definition of the entity or includes another file containing the definition.Implicit inclusion
When the compiler sees a template declaration in a.h
file and discovers a need to instantiate that entity, it looks for a source file with the same base name as the.h
file and a suffix that satisfies the conventions for C++ source file names (.C
,.CPP
,.CXX
or.CC
). This file is then implicitly included by the compiler on instantiation at the end of each compilation unit without a message being issued. Further details see the section“Implicit inclusion”.The programmer makes sure that the files that define template entities also contain the definitions of all required types and adds C++ code or instantiation pragmas in those files to request the instantiation of the template entities therein.
First instantiation without a definition list
The definition list method can also be used as an alternative to the following procedure (see "First instantiation with the help of the definition list (temporary repository)").
The following steps are performed internally during automatic instantiation:
Create instantiation information files
The first time that one or more source files are compiled with the COMPILE statement, no template entities are instantiated. For each source file that makes use of a template, an associated instantiation information file is created if no such file exists. This instantiation information file is placed in the PLAM library of the module to be generated and is assigned the base name of the module with the suffix.II
by default (see the section“Rules for constructing module names”). For example, if a source programnamed
ABC.CC
were to be compiled (without explicitly specifying a module name), the fileABC.II
would be generated as the instantiation information file. This file must not be modified by the user.Create modules
The created modules contain information on which instantiations could have been created and on those possibly required when compiling a source file.Assign template instantiations
When the modules are linked with the BIND statement, the prelinker is called before the actual linking takes place. The prelinker examines the modules, looking for references and definitions of template entities and for additional information about entities that could be instantiated. If the prelinker cannot find a definition for a required template entity, it looks for a module that indicates that it could instantiate that template entity. When it finds such a module, it assigns the instantiation to it.Update the instantiation information file
All instantiations that were assigned to a given module are recorded by name in the associated instantiation information file.Recompile
The compiler is internally called again to recompile each file for which the instantiation information file was changed.Create new modules
When the compiler compiles a file, it reads the instantiation information file for that compilation unit and generates a new module with the required instantiations (i.e. template definitions).Repetition Steps 3 to 6 are repeated until all instantiations which are required and which can be generated have been created.
Linkage
The modules are linked together.
First instantiation with the help of the definition list (temporary repository)
Since the method above (see "First instantiation without a definition list") needs to recompile some files more than once, an option was added to accelerate the entire process.
When this option is used, the files are generally only recompiled once. Most of the instantiations are assigned to the first few files to be recompiled in this process. This results in disadvantages in some cases since the object size increases due to this (although other objects decrease in size to balance this out).
Steps 3-5 above are modified. The resulting algorithm appears as follows:
Create instantiation information filesThe first time that one or more source files are compiled with the COMPILE statement, no template entities are instantiated. For each source file that makes use of a template, an associated instantiation information file is created if no such file exists. This instantiation information file is placed in the PLAM library of the module to be generated and is assigned the base name of the module with the suffix
.II
by default (see the section“Rules for constructing module names”). For example, if a source program namedABC.CC
were to be compiled (without explicitly specifying a module name), the fileABC.II
would be generated as the instantiation information file. This file must not be modified by the user.Create modulesThe created modules contain information on which instantiations could have been created and on those possibly required when compiling a source file.
Assign template instantiations to a source fileIf there are references for template entities for which there are no definitions in the set of modules, then a file that could instantiate one of the template entities is selected. All template entities that can be instantiated in this file are assigned to the file.
Update the instantiation information fileThe set of instantiations that were assigned to the file are recorded by name in the associated instantiation file.
Store the definition listA definition list is stored internally in memory. It contains a list of all definitions found in all modules that relate to templates. This list can be read in and changed during recompilation.
NoteThis list is not stored in a file.
RecompileThe compiler is internally called again to recompile the corresponding source files.
Create new modulesWhen the compiler recompiles a file, it reads the instantiation information file for that compilation unit and generates a new module with the required instantiations.When the compiler obtains an opportunity during compilation to instantiate additional template entities that are not mentioned in the definition list and were not found in the libraries resolved, then it will also instantiate these (e.g. for templates that are contained in templates). It sends the list of instantiations that it obtained during recompilation to the prelinker so that the prelinker can assign it to the file.
This process results in faster instantiations and reduces the necessity of recompiling an existing file more than once during the prelinking process.
Repetition Steps 3 to 7 are repeated until all instantiations that are required and can be generated have been created.
LinkageThe modules are linked together.
Further development
Once a program has been correctly linked, the associated instantiation information files contain all the names of the defined and required instantiations. From then on, whenever source files are compiled, the compiler will consult the instantiation information file and do the instantiations therein as in a normal compilation run. In other words, except in cases where the set of required instantiations changes, the prelinker will find all required instantiations stored in the modules, so no further instantiation adjustments are needed. This applies even if the entire program is recompiled.
If a specialization of a template entity has been provided somewhere in the program, the prelinker will treat it as a definition. Since this definition will satisfy any references to the template entity, the prelinker will see no need to request an instantiation for that template entity. If a specialization is added to a program that has already been compiled, the prelinker will remove the assignment of the instantiation from the corresponding instantiation information file.
The instantiation information file must not be modified (e.g. renamed or deleted) by the user, except in the following case: if a source file in which a definition was changed and another source file in which a specialization was added are being compiled in sequence in the same compiler run, and the compilation of the first file (with the changed definition) has aborted with an error, the associated instantiation information file must be deleted manually to allow the prelinker to regenerate it.
Interaction between the compilation and prelinker runs
Since the automatic template instantiation by the prelinker can, among other things, also involve subsequent compilations, the conditions under which the compilation occurs (COMPILE) play an important role in the prelinker run (BIND ACTION=*PRELINK,...) as well. Technically speaking, all options relevant for the compilation, code generation and compiler outputs are entered in the corresponding instantiation information files and interpreted during the automatic template instantiation. In order to ensure that the follow-up compilations and other updates function correctly during instantiation, the following points, in particular, must be observed:
The input of source programs via SYSDTA and the output of listings to SYSLST or SYSOUT are not supported and are rejected with a corresponding error message.
All I/O files and libraries of the compilation run must also be locatable and accessible in the prelinker run and should hence be neither renamed nor deleted. If the prelinker run occurs in some other environment (e.g. user ID), fully-qualified file names must be used in the compilation, i.e., names including the <cat-id> and <user-id> for BS2000 files and PLAM libraries, and absolute path names (beginning with /) for POSIX files.
The *INCREMENT option is not permitted for the following output files:
module element name
cif element name
listing element name
Warning: Compilation is aborted in this case.
When you specify an explicit version string for ’module name’, an ii-element file with the same version string is searched for, read in and written. (If an existing ii-element with a different version string is to be used, then this element must be copied and stored under a new name before it can be linked and before the template instantiation starts.) This behavior is not compatible with the C++ Compiler V3.0.
Prelinking and dynamic linkage
The prelinker does the automatic instantiation only in the individual modules generated by the compiler, since it requires the unique assignment between the module and the instantiation file (.II
file) for this purpose. The prelinker is activated only with the BIND statement of the compiler (ACTION=*PRELINK). If only ACTION=*MODULE-GENERATION is specified in the BIND statement, no template instantiation is performed.
When generating the finished program (via static or dynamic linkage), all “prelinked modules” of the the BIND statement and all dynamically linked modules that require instances of template entities must either
already contain these instances (which may be achieved by explicit instantiation and/or the preinstantiation of modules with the BIND statement (ACTION=*PRELINK)
or provide appropriate headers with
can_instantiate
pragmas.
During the preinstantiation with the BIND statement, it is absolutely essential to ensure that the C++ libraries and C++ runtime systems of the CRTE (standard C++ library, C++ runtime system, Tools.h++ library) are also considered by the prelinker, since duplicate definitions may otherwise be created. The libraries are automatically taken into account if the STDLIB option of the MODIFY-BIND-PROPERTIES statement is set to *DYNAMIC or *STATIC and the TOOLSLIB option is set to *YES. If the CRTE libraries are to be linked in dynamically themselves, duplicate definitions can be prevented as follows:
The first step is to preinstantiate the modules, taking the used CRTE libraries into account:
//MODIFY-BIND-PROPERTIES STDLIB=*DYNAMIC / *STATIC [,TOOLSLIB=*YES], ...//BIND ACTION=*PRELINK,
...All modules with unresolved external references to the used CRTE libraries can then be linked in a second step:
//MODIFY-BIND-PROPERTIES STDLIB=*NONE [,TOOLSLIB=*NO], ...//BIND ACTION=*MODULE-GENERATION,
...
If the prelinker and linkage runs are to be executed concurrently, the ADD-PRELINK-FILES option must be used. The main disadvantage of this method is that the names of the CRTE libraries would then need to be specified explicitly.
In the case of a standard installation of the CRTE and in mode C++ V3, for example, this is achieved as follows:
//MODIFY-BIND-PROPERTIES ADD-PRELINK-FILES=(*LIB(LIB=$.SYSLNK.CRTE.STDCPP),*LIB(LIB=$.SYSLNK.CRTE.RTSCPP)
[,*LIB(LIB=$.SYSLNK.CRTE.TOOLS)] ),- STDLIB=*NONE, ...//BIND ACTION=(*PRELINK,*MODULE-GENERATION),
...