Skip Navigation Links | |
Exit Print View | |
What's New in the Oracle Solaris Studio 12.3 Release Oracle Solaris Studio 12.3 Information Library |
1. Introducing the Oracle Solaris Studio 12.3 Release
7. The Oracle Solaris Studio IDE
9. Known Problems, Limitations, and Workarounds in This Release
Issues Common To The Compilers
Apache Standard Library Issue on Solaris
Ambiguity: Constructor Call or Pointer-to-Function
Linking Fails If You Combine -xipo or -xcrossfile With -instances=static
Name Mangling Linking Problems
No Support For Referencing a Non-Global Namespace Object From a Template
#pragma align Inside Namespace Requires Mangled Names
Array Intrinsic Functions Use Global Registers:
F95 Modules in Archive Libraries Not Included In Executable:
Known dbx issues and Workarounds
This section describes known issues, problems, and workarounds for the compilers in this release.
Errors in the published compiler documentation are listed below.
The cc(1), CC(1), and f95(1) man pages neglect to list the —xarch=sse3a flag, which adds the AMD instruction set, including 3dnow, to the SSE3 instruction set.
The C and C++ documentation neglects to point out that the —xMF option can only be used with —xMD or —xMMD, but not with —xM or —xM1. When specified, it overrides the default .d file name used with those options.
The Apache stdcxx library installed in Solaris 10u10 and earlier and in the initial release of Solaris 11 has a syntax error in header stdcxx4/loc/_moneypunct.h. This error was not seen by earlier compilers, but is caught by the Oracle Solaris Studio 12.3 C++ compiler. There is no way to disable the error detection.
A fix for this bug is available in a patch for Solaris 10, and in the first Solaris 11 SRU. The fix will be included in Solaris 10u11 and Solaris 11u1 when they become available.
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
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.
The following conditions may cause linking problems.
A function is declared in one place as having a const parameter and in another place as having a non-const parameter.
Example:
void foo1(const int); void foo1(int);
These declarations are equivalent, but the compiler mangles the names differently. To prevent this problem, do not declare value parameters as const. For example, use void foo1(int); everywhere, including the body of the function definition.
A function has two parameters with the same composite type, and just one of the parameters is declared using a typedef.
Example:
class T; typedef T x; // foo2 has composite (that is, pointer or array) // parameter types void foo2(T*, T*); void foo2(T*, x*); void foo2(x*, T*); void foo2(x*, x*);
All declarations of foo2 are equivalent and should mangle the same. However, the compiler mangles some of them differently. To prevent this problem, use typedefs consistently.
If you cannot use typedefs consistently, a workaround is to use a weak symbol in the file that defines the function to equate a declaration with its definition. For example:
#pragma weak "__1_undefined_name" = "__1_defined_name"
Note that some mangled names are dependent on the target architecture. (For example, size_t is unsigned long for the SPARC V9 architecture (-m64), and unsigned int otherwise.) In such a case, two versions of the mangled name are involved, one for each model. Two pragmas must be provided, controlled by appropriate #if directives.
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.
You can give the variable external linkage:
int k; // not static
All instances use the same copy of k.
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.
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; }
The following issues should be noted in this release of the f95 compiler:
Blank space before the end of a no advance print line does not affect output position (7087522).
Having the X edit descriptor at the end of a format of an output statement does not affect the position of the next character in the output record. This causes a difference if the output statement has ADVANCE='NO' and there are more characters to be transferred to the same record by subsequent output statements.
In many cases, this can be worked around by having a blank character string edit descriptor instead of the nX edit descriptor. They are not exactly the same since the blank character string edit descriptor actually causes blank characters to go into the record whereas the nX only skips over the next n characters, usually causing blanks to be in those skipped positions by default.
Valid code rejected when a line consists of two continuation ampersands. (7035243).
An empty continuation line with a single ampersand is forbidden by the Fortran standard. However, with two ampersands on the same line, an empty continuation line can still be created without falling under the standard restriction. The compiler does not handle that case and gives an error. The workaround is to delete that line which only affects the readability of the program without adding any semantics.
BOZ constants sometimes get truncated (6944225).
In some relatively more complex scenarios, such as an array construct, a BOZ constant might get truncated to the default integer size of 4 bytes even though the corresponding item it is supposed to be assigned to is an 8-byte integer entity. The workaround is to use constants of correct type and kind in array construct instead of BOZ constants.
Previous releases of the Fortran compiler introduced incompatibilities that carry forward to this release of the compiler and should be noted if you are updating from earlier Fortran compiler releases. The following incompatibilies are worth noting:
Here is a reminder that the Oracle Solaris Studio 12.2 release removed the obsolete FORTRAN 77 libraries. This means that old executables compiled with the legacy Sun WorkShop f77 compiler that depend on the shared libraries libF77, libM77 and libFposix will not run.
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.
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.
There is no reliable way to accurately obtain the clock rate on AMD processors when system power saving is enabled. As a result, using timing functions based on gethrtime(3F) (the Fortran compiler's Linux version of the Solaris gethrtime(3C) function) to get high resolution real time on Linux platforms will only be accurate on AMD systems with power saving disabled. A reboot of the system might be required to disable the power-saving features.