Go to main content
Oracle® Developer Studio 12.5: C++ User's Guide

Exit Print View

Updated: July 2016
 
 

1.1 New Features and Functionality of the Oracle Developer Studio 12.5 C++ 5.14 Compiler

This section provides a summary list of the new features and changed functionality introduced in the Oracle Developer Studio 12.5 C++ 5.14 Compiler release.

  • Support for SPARC M6, M7, and T7 processors.

  • Support for the Intel Broadwell/avx2_i processor.

  • Support for x86 dataspace profiling.

  • The default compilation mode on Oracle Solaris is –compat=5 with –library=Cstd (C++03 mode with the Sun ABI and libCstd library). The default compilation mode on Oracle Linux is –std=c++03 (C++03 mode with the g++ ABI and runtime libraries).

  • In –compat=5 mode on all platforms, correct name mangling is now the default. Previously, bugs in name mangling were the default on SPARC, and on x86 with –m32.

  • New compiler options:

    • –abiopt=[mangle5|mangle6] is available only in –compat=5 mode. The default is mangle6, correct name mangling. On Oracle Solaris SPARC, and on Oracle Solaris x86 with –m32, you can specify mangle5 for compatibility with possibly buggy name mangling of older compilers.

    • –features=[no%]mergestrings causes the compiler to put string literals and other suitable const or read-only data into a special section of the binary where the linker removes duplicate strings. This option is available only on SPARC.

    • –pedantic emits warnings or errors for code that is accepted by default but does not conform to the C++ Standard.

    • –xatomic specifies which atomics support runtime library is linked.

    • –xcheck=noreturn informs the compiler to add code to cause a runtime error if a routine which has been described as "do not return" returns.

    • –xsecure_code_analysis enables compiler secure code analysis to find and display possible memory safety violations at compile time.

1.1.1 C++11 Standard

Oracle Developer Studio 12.5 provides full support for C++11.

The g++ 4.8.2 library provided with Oracle Solaris Studio 12.4 did not follow all of the requirements of C++11. The standard string and list classes in particular required changes that would break binary compatibility.

The g++ 5.1 release provides a choice of compatibility with g++ 4.x or conformance to the C++ standard. The choices are mutually incompatible. More detailed information about using g++ is available in the article GCC5 and the C++11 ABI (http://developerblog.redhat.com/2015/02/05/gcc5-and-the-c11-abi).

Oracle Developer Studio 12.5 in –std=c++11 or –std=c++14 modes provides compatibility with Oracle Solaris Studio 12.4 and g++ 4.8.2. Oracle Developer Studio 12.5 does not provide the incompatible standard-conforming option.

If you want to combine g++ 5.1 binaries with Oracle Developer Studio binaries, the g++ binaries must all be compiled using the –D_GLIBCXX_USE_CXX11_ABI=0 option on every g++ command line.

1.1.2 C++14 Standard

Oracle Developer Studio 12.5 provides limited support for the C++14 Standard. The following features are supported:

  • Binary literals

  • Sized deallocation

  • deprecated attribute

  • Single-quote digit separator

  • Member initialization and aggregates

1.1.3 Support for Atomics

Atomics is a new language feature in the C++ 2011 standard. The atomics feature is available only with the –std=c++11 and –std=c++14 options. For information about the functions and types supported, see the C++ Language Standard and the atomic_fence(3A), atomic_flag(3A), and stdatomic.h(3A) man pages.

The atomics feature requires runtime support. For more information about the runtime library, see Bundled Atomics Library.

1.1.4 Enforcement of C++ Rules

The Oracle Developer Studio 12.5 C++ 5.14 compiler enforces some C++ rules more strictly than past compilers. The incorrect rule enforcement caused earlier compilers to treat some valid code incorrectly. This section explains the stricter enforcement, provides examples of offending code, and shows how to fix the code. In all cases, you can change your code and it should still work with old and new compilers.

1.1.4.1 Template definition parsing

Previous compilers did not parse template definitions until the template was instantiated, with the following consequences:

  1. Previous compilers would allow use of names not declared until after the template definition. Invalid code could be accepted, valid code could be rejected due to an apparent conflict, or the wrong declaration could be used.

  2. Unconditional errors in templates that were not instantiated would not be diagnosed.

  3. Names in a the definition of template T that do not depend on template parameters would not be instantiated until T was instantiated. They should be instantiated implicitly at the point where T is defined.

Example 1:

template< class T > int f(int i = j) // j is not visible
  { return i; }
int j = 2;
int main()
{
    return f<int>();
}

Older compilers accepted this code because template f was not parsed until after j was defined.

Solution: Move the declaration of j ahead of the template.

Example 2:

#include <stdio.h>
void f(double d) { printf("f(double)\n"); }
template< class C > struct B {
    B() { f(1); } // f is not dependent on template parameter
};
void f(int d) { printf("f(int)\n"); }
int main()
{
    B<int> b; // should print "f(double)"
}

Solution: Be sure any declarations that the template should depend on occur before the template definition.

1.1.4.2 Dependent base lookup

When looking up an unqualified name in a template definition, base classes that depend on a template parameter should not be examined. Previous compilers did incorrect name lookup.

Example:

template <typename T> struct Base { };

template <typename T> struct Derived : Base <T>
{
    Derived() : Base() { } // unqualified Base should not be found
};
Derived <int> x;

template <typename T> struct Derived2 : Base <T>
{
    Derived2() : Base<T>() { } // OK
};
Derived2<int> x2;

int main() { }

In class Derived, the use of unqualified Base without template arguments is not valid.

Solution: In class Derived2, the usage is correct.

1.1.4.3 Re-declaring template parameters

You can no longer re-declare the name of a template parameter.

Example:

template <typename T> class A { typedef int T; }; // re-declare T

Solution: Pick a different name for the template parameter or for the local name.

1.1.4.4 Forward template declarations

Forward template declarations are no longer supported.

Example:

$ cat x.cc
template <> struct A<int>;
.
$ CC x.cc
"x.cc", line 1: Error: A class template name was expected instead of A<int>.

Previous releases of Oracle Developer Studio C++ would silently accept this as explicit specialization of implicitly declared template by the name "A" with one type parameter.

Solution: Declare the primary template before any explicit specializations.

template<class T> struct A;

template <> struct A<int>;

1.1.4.5 Old-style explicit instantiations

The pre-1998 style of declaring an explicit specialization without template<> is no longer allowed.

Example:

template <typename T> class A { static T m; };
int A<int>::m = 0; // now an error

Solution:

template<> int A<int>::m = 0;

1.1.4.6 Stricter -template=extdef

Refer to Template Definitions Separate. The "template definitions separate" compilation model is now more strict. When creating the X.cc file that has the definitions of templates declared in header X.h, you must be especially careful not to have anything else (that is, other than items directly associated with the definitions) in that file. You are now more likely to get "multiple definition" errors if you violate the rule.

Example:

% cat extdef.h
template <typename T> T foo(T);
% cat extdef.cc
#include "extdef.h"
int main() {
        foo(1);
}
% CC extdef.cc -template=extdef
"extdef.cc", line 3: Error: main() already had a body defined.
1 Error(s) detected.

Solution: Remove everything from the X.cc file that is not needed for the template definitions. Recall that the X.cc file is not supposed to be explicitly compiled, because it is automatically included whenever the X.h file is included.

If extensive changes are needed, you might consider compiling with the -template=no%extdef option. That behavior is the default for other compilers, and is now the default in this release.

1.1.4.7 Implicit int

An implicit declaration of type int was never allowed in C++, but earlier compilers sometimes allowed it with a warning. Due to the way it interferes with proper template handling, the compiler no longer assumes you meant to declare something type int.

Example:

static i = 0; // now an error

Solution: Provide the type explicitly in the declaration.

1.1.4.8 Friend declarations

When a friend declaration in class C for a function or class T was the first declaration of T, previous compilers incorrectly inserted the declaration of T into the surrounding scope. The Oracle Developer Studio 12.5 C++ 5.14 compiler no longer does so, because it can lead to incorrect interpretation of valid programs.

Example:

class A
{
    friend class B;    // not previously declared
    friend void foo(); // not previously declared

    B* bar() // Error: B is not defined.
    {
        foo(); // Error: The function "foo" must have a prototype.
        return 0;
    }
};

Solution: Declare the friend function or class in a scope outside the class before the class declaration that declares it a friend

class B;
void foo();
class A
{
    friend class B;    // refers to prior declaration
    friend void foo(); // refers to prior declaration

    B* bar() // OK
    {
        foo(); // OK
        return 0;
    }
};

A friend declaration that specifies a default argument must also be the function definition.

Example:

class C {
    friend int f1(int i = 0); // Error
    friend int f2(int i = 0) { return i; } // OK
}

Prior releases of the C++ compiler did not enforce this rule. Allowing default arguments in friend declarations interferes with proper template handling, and so is no longer allowed.

1.1.4.9 Static functions and name lookup in templates

  1. When looking up names in a dependent function call, previous compilers incorrectly ignored static functions that were in scope. The Oracle Developer Studio 12.5 C++ 5.14 compiler now treats static and extern functions the same way.

    Example:

    // previous compiliers ignored this bar() in dependent name lookup
    static int bar(int)
    {
            return 1;
    }
    int bar(long)
    {
            return 0;
    }
    template <typename T>
    int foo(T t)
    {
    	// function call depends on template argument
            return bar(t);
    }
    int main()
    {
            return foo(0);
    }

    Compiled with previous compilers, the program would return 0. With the Oracle Developer Studio 12.5 C++ 5.14 compiler, the program returns 1.

  2. When only a static function was found in name lookup, previous compilers would issue an error like

    "Reference to static bar(int) not allowed in template foo(int), 
    try using -features=tmplrefstatic."

    See the previous example, with extern function bar(long) removed. The compiler now issues only a warning in -compat=5 mode because the code is technically an extension to the C++03 standard. In C++11 mode, the code is silently accepted because it is valid C++11.

  3. The option -features=no%tmplrefstatic is still accepted, but has no net effect because references to static objects from templates are always allowed.

1.1.4.10 const correctness

Prior compilers did not enforce all the rules that preserve the properties of the keyword const.

Example:

void f1(int**) { printf("f1(int**)\n"); }
void f2(int**) { printf("Error: f2(int**)\n"); }
void f2(...)   { printf("OK: f1(...)\n"); }
int main()
{
  int* const p = 0;
  f1(&p);         // #1 Should be an error
  f2(&p);         // #2 Should choose f2(...)
}

Earlier compilers incorrectly accepted #1, and for #2 incorrectly called f2(int**). As line #2 shows, the wrong overloaded function, or an incorrect template specialization, could be selected due to the compiler's incorrect behavior.

Line #1 can be fixed either by declaring

int* p = 0;

or by changing the definition of f1 or adding the overload

void f1(int * const*);

If you prefer that existing invalid code continue to compile, you can add the undocumented option

-W0,-xconstcheck=false [note: W-zero, not W-oh]

to CC command lines that now produce complaints about const correctness.