JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
What's New In The Oracle Solaris Studio 12.2 Release
search filter icon
search icon

Document Information

Preface

1.  Introducing The Oracle Solaris Studio 12.2 Release

2.  Compilers

3.  Libraries

4.  Performance Analysis Tools

5.  Debugging Tools

6.  The Solaris Studio IDE

7.  Other Tools

8.  Known Problems, Limitations, and Workarounds in This Release

Compilers

Issues Common To The Compilers

Known problems related to --xprofile

C++

Correct Interpretation of Large Decimal Integer Constants

Ambiguity: Constructor Call or Pointer-to-Function

Template Syntax Error is No Longer Ignored

Linking Fails If You Combine -xipo or -xcrossfile With -instances=static

Cross-Language Linking Error

Name Mangling Linking Problems

Debugging Tools Erroneously Report Extra Leading Parameter for Member Functions

No Support For Referencing a Non-Global Namespace Object From a Template

#pragma align Inside Namespace Requires Mangled Names

Function Overload Resolution

Fortran

Array Intrinsic Functions Use Global Registers:

F95 Modules in Archive Libraries Not Included In Executable:

Tools

dbx

Known dbx issues and Workarounds

dbx Limitations and Incompatibilities

Performance Analyzer

dmake

dmake Limitations

Installation

Index

Compilers

This section describes known issues, problems, and workarounds for the compilers in this release.

Issues Common To The Compilers

Known problems related to —xprofile

C++

Correct Interpretation of Large Decimal Integer Constants

The C++ standard says that a decimal integer constant without a suffix is treated as an int if the value fits in an int, otherwise as a long int. If the value does not fit in a long int, the results are undefined.

In 32-bit mode, types int and long have the same size and data range. The C++ compiler followed the 1990 C standard rule, treating a value between INT_MAX+1 and LONG_MAX as unsigned long. This treatment produced unexpected results in some programs.

The 1999 C standard changed the rule about unsuffixed decimal integers so that they are never treated as unsigned types. The type is the first of int, long, or long long that can represent the value.

The C++ compiler follows the C99 rule when in standard mode, but continues to follow the C90 rule in -compat=4 mode. (In -compat=4 mode, the compiler behaves like the C++ 4.2 compiler.)

If you want a large decimal integer to be treated as unsigned, the portable solution is to use a u or U suffix. You can use the other suffixes for other types as well. For example:

              // note: 2147483648 == (INT_MAX+1)
              2147483648     // (signed) long long
              2147483648LL   // (signed) long long
              2147483648U    // same as 2147483648u
Ambiguity: Constructor Call or Pointer-to-Function

Some C++ statements could potentially be interpreted as a declaration or as an expression-statement. The C++ disambiguation rule is that if a statement can be a declaration, it is a declaration.

Earlier versions of the compiler misinterpreted cases like the following:

          struct S {
            S();
          };
          struct T {
            T( const S& );
          };
          T v( S() );    // ???

The programmer probably intended the last line to define a variable v initialized with a temporary of type S. Previous versions of the compiler interpreted the statement that way.

But the construct "S()" in a declaration context can also be an abstract declarator (that is, one without an identifier) meaning "function with no parameters returning of value of type S." In that case, it is automatically converted to the function pointer "S(*)()". The statement is thus also valid as a declaration of a function v having a parameter of function-pointer type, returning a value of type T.

The compiler now makes the correct interpretation, which might not be what the programmer intended.

There are two ways to modify the code to make it unambiguous:

          T v1( (S()) );  // v1 is an initialized object
          T v2( S(*)() ); // v2 is a function

The extra pair of parentheses in the first line is not valid syntax for v1 as a function declaration, so the only possible meaning is "an object of type T initialized with a temporary value of type S."

Similarly, the construct "S(*)()" cannot possibly be a value, so the only possible meaning is as a function declaration.

The first line can also be written as

T v1 = S();

Although the meaning is completely clear, this form of initialization can sometimes result in extra temporaries being created, although it usually does not.

Writing code like the following is not recommended because the meaning is not clear, and different compilers might give different results.

T v( S() ); // not recommended

Template Syntax Error is No Longer Ignored

The following template syntax has never been valid, but Sun C++ 4 and 5.0 did not report the error. All versions since 5.1 of the C++ compiler report this syntax error when you compile in standard mode (the default mode).

        template<class T> class MyClass<T> { ... }; // definition error
        template<class T> class MyClass<T>; // declaration error

In both cases the <T> in MyClass<T> is invalid and must be removed, as shown below:

        template<class T> class MyClass { ... }; // definition
        template<class T> class MyClass; // declaration
Linking Fails If You Combine -xipo or -xcrossfile With -instances=static

The template option -instances=static (or -pto) does not work in combination with either of the -xcrossfile or -xipo options. Programs using the combination will often fail to link.

If you use the -xcrossfile or -xipo options, use the default template compilation model, -instances=global instead.

In general, do not use -instances=static (or -pto) at all. It no longer has any advantages, and still has the disadvantages documented in the C++ Users Guide.

Cross-Language Linking Error

The -xlang=f77 command-line option causes the compilation process to encounter a linker error. To avoid the error and still include the appropriate runtime libraries, compile with-xlang=f77,f90 instead.

Name Mangling Linking Problems

The following conditions may cause linking problems.

Debugging Tools Erroneously Report Extra Leading Parameter for Member Functions

In compatibility mode (-compat), the C++ compiler incorrectly mangles the link names for pointers to member functions. The consequence of this error is that the demangler, and hence some debugging tools, like dbx and c++filt, report the member functions as having an extra leading parameter consisting of a reference to the class type of which the function is a member. To correct this problem, add the flag -Qoption ccfe -abiopt=pmfun1. Note, however, that sources compiled with this flag may be binary incompatible with sources compiled without the flag. In standard mode (the default mode), the problem does not occur.

No Support For Referencing a Non-Global Namespace Object From a Template

A program using templates and static objects causes link-time errors of undefined symbols if you compile with -instances=extern. This is not a problem with the default setting -instances=global. The compiler does not support references to non-global namespace-scope objects from templates. Consider the following example:

      static int k;
      template<class T> class C {
              T foo(T t) { ... k ... }
      };

In this example, a member of a template class references a static namesapce-scope variable. Keep in mind that namespace scope includes file scope. The compiler does not support a member of a template class referencing a static namespace-scope variable. In addition, if the template is instantiated from different compilation units, each instance refers to a different k, which means that the C++ One-Definition Rule is violated and the code has undefined behavior.

Depending on how you want to use k and the effect it should have, the following alternatives are possible. The second option only is available for function templates that are class members.

  1. You can give the variable external linkage:

                  int k; // not static 

    All instances use the same copy of k.

  2. You can make the variable a static member of the class:

                template<class T> class C {
                        static int k;
                        T foo(T t) { ... k ... }
                };    

    Static class members have external linkage. Each instance of C<T>::foo uses a different k. An instance of C<T>::k can be shared by other functions. This option is probably what you want.

#pragma align Inside Namespace Requires Mangled Names

When you use #pragma align inside a namespace, you must use mangled names. For example, in the following code, the #pragma align statement has no effect. To correct the problem, replace a, b, and c in the #pragma align statement with their mangled names.

        namespace foo {
          #pragma align 8 (a, b, c) // has no effect
          //use mangled names: #pragma align 8 (__1cDfooBa_, __1cDfooBb_, __1cDfooBc_)
          static char a;
          static char b;
          static char c;
        }
Function Overload Resolution

Early releases of the C++ compiler did not perform function overload resolution in accordance with the requirements of the C++ standard. The current release fixes many bugs in resolving calls to overloaded functions. In particular, the compiler would sometimes pick a function when a call was actually ambiguous, or complain that a call was ambiguous when it actually was not.

Some workarounds for ambiguity messages are no longer necessary. You may see new ambiguity errors that were not previously reported.

One major cause of ambiguous function calls is overloading on only a subset of built-in types.

      int f1(short);
      int f1(float);
      ...
      f1(1); // ambiguous, "1" is type int
      f1(1.0); // ambiguous, "1.0" is type double

To fix this problem, either do not overload f1 at all, or overload on each of the types that do not undergo promotion: int, unsigned int, long, unsigned long, and double. (And possibly also types long long, unsigned long long, and long double.)

Another major cause of ambiguity is type conversion functions in classes, especially when you also have overloaded operators or constructors.

      class T {
      public:
              operator int();
              T(int);
              T operator+(const T&);
      };
      T t;
      1 + t // ambiguous

The operation is ambiguous because it can be resolved as

        T(1) + t     // overloaded operator
       1 + t.operator int()    // built-in int addition

You can provide overloaded operators or type conversion functions, but providing both leads to ambiguities.

In fact, type conversion functions by themselves often lead to ambiguities and conversions where you did not intend for them to occur. If you need to have the conversion available, prefer to use a named function instead of a type conversion function. For example, use int to_int(); instead of operator int();

With this change, the operation 1 + t is not ambiguous. It can be interpreted only as T(1) + t. If you want the other interpretation, you must write 1 + t.to_int().

Fortran

The following issues should be noted in this release of the f95 compiler:

Previous releases of the f95 compiler introduced incompatibilities that carry forward to this release of the compiler and should be noted if you are updating from earlier f95 releases. The following incompatibilies are worth noting:

Array Intrinsic Functions Use Global Registers:

The array intrinsic functions ANY, ALL, COUNT, MAXVAL, MINVAL, SUM, PRODUCT, DOT_PRODUCT, and MATMUL are highly tuned for the appropriate SPARC platform architectures. As a result, they use the global registers %g2, %g3, and %g4 as scratch registers.

User code should not assume these registers are available for temporary storage if calls are made to the array intrinsics listed above. Data in these registers will be overwritten when the array intrinsics are called.

F95 Modules in Archive Libraries Not Included In Executable:

The debugger dbx requires all object files used in the compilation to be included in the executable file. Usually, programs satisfy this requirement with no extra work on the part of the user. An exceptional case arises from the use of archives containing modules. If a program uses a module, but does not reference any of the procedures or variables in the module, the resulting object file will not contain references to the symbols defined in the module. The linker only links with a object file from an archive if there is a reference to a symbol defined in the object file. If there is no such reference, the object file will not be included in the executable file. Dbx will give a warning when it tries to find the debugging information associated with the module that was used. It will not be able to provide information about the symbols whose debugging information is missing.

Use the -u linker option to work around this problem. This option takes a symbol as its option argument. It adds that symbol to the set of undefined linker symbols, so it will have to be resolved. The linker symbol associated with a module is normally the module name with all letters in lower case followed by an underscore.

For example, to force the object file containing the module MODULE_1 to be taken from an archive, specify the linker option -u module_1_. If linking using the f95 command, use -Qoption ld -umodule_1_ on the command line.