Understanding the Effects of the Changed Default C++ Template Compilation Model

in Oracle Solaris Studio 12.4
by Steve Clamage

Learn how the change in the Oracle Solaris Studio default template compilation model affects your code.

Published September 2014 (updated September 2014)


About the Author
Stephen ClamageSteve Clamage is a senior engineer in the Oracle Solaris Studio team and project lead for Oracle's C++ compiler. He has been the chair of the U.S. C++ Standards Committee since 1996.
See Also
- Oracle Solaris Studio
- Studio Forums
- Tech Articles for Developers
Follow OTN
OTN Homepage

In Oracle Solaris Studio 12.4, the default template compilation model has changed from the definitions-separate model used in Oracle Solaris Studio 12.3 and earlier releases to the definitions-included model. Most applications will benefit from this change. Some will need to add the explicit option -template=extdef to the Oracle Solaris Studio C++ compiler (CC) command line to revert to the behavior of the earlier releases. This article explains the change and how it might affect building your C++ applications.

Background

Chapter 5 of the Oracle Solaris Studio 12.4: C++ User's Guide discusses two ways to organize template source code:

  • Definitions-separate. A header file provides the declaration (interface) of one or more templates, and a separate .cc file has the definitions. The .cc file is included where needed. The corresponding C++ compiler option is -template=extdef.
  • Definitions-included. The template definitions are provided along with the template declarations. The corresponding C++ compiler option is -template=no%extdef.

Historically, the Oracle Solaris Studio C++ compiler followed the template compilation model introduced by Cfront, the first C++ compiler. Therefore, by default, the compiler assumed the definitions-separate model. If a header file foo.h had template declarations, for any compilation where the template definitions were required, the compiler automatically included foo.cc.

Note: This article uses .cc as the C++ source file extension. The discussion applies equally to the other extensions recognized by the Oracle Solaris Studio C++ compiler: .c, .cpp, .C, .c++, and .cxx.

Definitions-Separate Model and Source Code Organization

The definitions-separate model imposes the following requirements on source code organization.

  • Any template definitions missing from foo.h are assumed to be in foo.cc.
  • File foo.cc must not contain anything other than template definitions missing from foo.h.
  • File foo.cc must not include foo.h.
  • File foo.cc must not be separately compiled.

The reason for these restrictions should be obvious if you reflect on the fact that foo.cc is usually included automatically wherever foo.h is included.

Examples of Source Code Organization

Listing 1 shows a definitions-separate organization for the function template times2.

File times2.h
template<class T> T times2(T val);
File times2.cc
template<class T> T times2(T val) { return val*2; }

Listing 1. Template times2, definitions-separate.

In Listing 1, file times2.cc is expected to be automatically included when needed.

Listing 2 shows a definitions-included organization for template times2.

File times2.h
template<class T> T times2(T val) { return val*2; }

Listing 2. Template times2, definitions-included.

In Listing 2, the definition of the template is included in the header. There is no separate .cc file.

Listing 3 shows an alternative organization for the definitions-included model.

File times2.h
template<class T> T times2(T val);
#include "times2.cc"
File times2.cc
template<class T> T times2(T val) { return val * 2; }

Listing 3. Template times2, alternative definitions-included.

In Listing 3, the template definition is in a separate file, but the file is explicitly included via the #include directive.

Changes to the Template Definition Model in Oracle Solaris Studio 12.4

Prior releases of Oracle Solaris Studio were probably unique among compilers in assuming the definitions-separate template model. Code developed originally with other compilers often conflicts with that model, and often will not build when the -template=extdef option is in effect. Some popular open source code—recent versions of Boost, in particular—will not build. Developers often need to add -template=no%extdef to CC command lines to get code to build.

For these reasons, the Oracle Solaris Studio team has changed the default behavior in Oracle Solaris Studio 12.4 so that definitions-separate is no longer the default model. The default for the -template option has changed from -template=extdef to -template=no%extdef.

Consequences of Compiling with the Wrong Template Model

What happens if the actual source code model—definitions included or separate—does not match the model the compiler expects? There are two possibilities:

  • If the -template=extdef option (the default model for compiler versions before Oracle Solaris Studio 12.4) is in effect but the definitions-separate model is not followed, the file foo.cc can be compiled more than once, leading to multiple-definition errors at compile or link time.
  • If the -template=no%extdef option (the default model for the Oracle Solaris Studio 12.4 compiler) is in effect but the definitions-separate model is followed, the file foo.cc is never compiled, so you can get missing-definition errors at compile or link time.
  • OK, there are three possibilities. The code might compile and link by accident, but it could fail later, when source code changes are made.

Issues with Apache stdcxx Library

As of this writing, the Oracle Solaris version of the Apache stdcxx library that is selected by the option -library=stdcxx4 is not compatible with the new default option -template=no%extdef. You might see warnings at compile time that start with Warning: Could not find source for __rw:: and involve internals of the library. You might see errors at link time about missing symbols whose names include __rw::.

Until an updated version of the library is available, you might need to add -template=extdef to CC command lines that have -library=stdcxx4.

What Changes Do You Need to Make?

Apart from the issues with Apache stdcxx, if you explicitly use either of the -template=[no%]extdef options, you don't need to change anything. The only difference in Oracle Solaris Studio 12.4 is the default compiler behavior when neither of these options is specified.

If you have code developed exclusively with Oracle Solaris Studio C++, or code that depends on the definitions-separate template model, you will probably need to add the option -template=extdef to your CC command lines, in order to revert to the behavior of the Oracle Solaris 12.3 and earlier compilers.

Alternatively, you could consider modifying the organization of your source code so that it works with either template compilation model. Listing 2 above, with template definitions in the header file and no corresponding .cc file, is an example of code that works with either model.

Finally, these options affect only building C++ programs. They do not affect the meaning of C++ programs after they build successfully.

See Also

Oracle Solaris Studio 12.4: C++ User's Guide

Revision 1.0, 09/12/2014
Revision 1.1, 09/23/2014
Added "Issues with Apache stdcxx Library" section

Follow us:
Blog | Facebook | Twitter | YouTube