JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
Oracle Solaris Studio 12.2 リリースの新機能
search filter icon
search icon

ドキュメントの情報

はじめに

1.  Oracle Solaris Studio 12.2 リリースの概要

2.  コンパイラ

3.  ライブラリ

4.  パフォーマンス解析ツール

5.  デバッグツール

6.  Solaris Studio IDE

7.  その他のツール

8.  このリリースでの既知の問題、制限事項、および回避策

コンパイラ

コンパイラに共通する問題

-xprofile に関する問題

C++

サイズの大きい 10 進整定数の適切な解釈

あいまいさ: コンストラクタ呼び出しまたは関数へのポインタ

テンプレートの構文エラーの検出

-instances=static で -xipo または -xcrossfile があると、リンクに失敗する

言語間リンクエラー

リンク時の名前符号化の問題

デバッグツールから、メンバー関数に余分な先行パラメータがあるという誤ったメッセージが返される

大域的ではない名前空間のオブジェクトをテンプレートから参照できない

名前空間内の #pragma align と符号化名

関数の多重定義の解決

Fortran

配列組み込み関数における大域レジスタの使用

アーカイブライブラリ内の F95 モジュールが実行可能ファイルに含まれない

ツール

dbx

dbx に関する既知の問題と回避策

dbx の制限事項と非互換性

パフォーマンスアナライザ

dmake

dmake の制限事項

インストール

索引

コンパイラ

ここでは、このリリースでのコンパイラに関する既知の問題および回避策について説明します。

コンパイラに共通する問題

-xprofile に関する問題

C++

サイズの大きい 10 進整定数の適切な解釈

C++ 規格では、接尾辞のない 10 進整定数は、値が int に収まる場合は int として、そうでない場合は long int として扱うようになっています。値が long int にも収まらない場合の結果は定義されていません。

32 ビットモードの場合、型 intlong のサイズおよびデータ範囲は同じです。1990 C 標準規則に準拠した C++ コンパイラは、INT_MAX+1 潤オ LONG_MAX の範囲にある値を unsigned long として処理します。この処理は、一部のプログラムでは予期しない結果をもたらします。

1999 C 規格では、接尾辞のない 10 進整数に関するこの規則が変更され、unsigned 型として扱われなくなりました。型は、intlonglong long のうちの最初に値を表せる型になります。

標準モードでは、C++ コンパイラはこの C99 規則に従いますが、-compat=4 モードではこれまでどおり C90 の規則に従います。-compat=4 モードでは、コンパイラは C++ 4.2 コンパイラのように動作します。

サイズの大きい 10 進整数を unsigned として扱う場合の移植可能な解決策は、u または U 接尾辞を使用することです。その他の型にも、それぞれ接尾辞を使用することができます。静的関数

              // note: 2147483648 == (INT_MAX+1)
              2147483648     // (signed) long long
              2147483648LL   // (signed) long long
              2147483648U    // same as 2147483648u
あいまいさ: コンストラクタ呼び出しまたは関数へのポインタ

C++ では、あるときは宣言と解釈されたり、またあるときは式と解釈される可能性がある文があります。C++ のあいまい排除規則では、ある文を宣言文とみなすことができる場合は、その文は宣言文とすることになっています。

従来のバージョンのコンパイラでは、次のような事例を誤って解釈していました。

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

このプログラマはおそらく、最後の行で S 型の一時的な値で初期化される変数 v を定義するつもりでした。従来のバージョンのコンパイラは、この文をそのように解釈していました。

しかし、宣言コンテキスト内のコンストラクト、"S()" は、"S 型の値を戻すパラメータのない関数" を意味する抽象宣言子 (識別子のない抽象宣言子) とみなすこともできます。この事例では、関数ポインタ、"S(*)()" に自動的に変換されています。この文はまた、戻り値が T 型で、パラメータが関数ポインタ型の関数 v の宣言としても有効です。

現在ではコンパイラが正しい解釈をするようになったので、このプログラマが意図したようにならない可能性があります。

あいまいにならないようにコードを修正するには、次の 2 通りの方法があります。

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

1 行目の 1 対の余分な括弧は、v1 の構文が関数宣言としては不正であるので、"S 型の一時的な値で初期化される T 型のオブジェクト" という意味にしか解釈できません。

同様に、コンストラクト "S(*)()" は値とは考えられないので、関数宣言の意味にしか解釈できません。

最初の行は、次のように書くこともできます。

T v1 = S();

意味は完全に明確になりますが、この初期設定の形式では、通常はそうでもないとはいえ、一時的な値として非常に大きな値が生成されることがあります。

次のようにコーディングするのはお勧めできません。その理由は、意味が不明確で、コンパイラが異なると結果が異なる可能性があるからです。

T v( S() ); // 推奨しない

テンプレートの構文エラーの検出

次のテンプレートの構文は不正ですが、Sun C++ 4 および 5.0 では、エラーになりませんでした。5.1 以降のすべてのバージョンの C++ コンパイラでは、標準モード (デフォルトのモード) のコンパイルで、構文エラーとして報告されます。

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

どちらの場合も、MyClass<T><T> は無効で、次に示すように削除する必要があります。

        template<class T> class MyClass { ... }; // definition
        template<class T> class MyClass; // declaration
-instances=static で -xipo または -xcrossfile があると、リンクに失敗する

テンプレートオプションの -instances=static (または -pto) を -xcrossfile-xipo オプションと組み合わせると、機能しません。この組み合わせを使用したプログラムは、リンクに失敗することがよくあります。

-xcrossfile または -xipo オプションを使用する場合は、デフォルトのテンプレートコンパイルモデルの -instances=global を使用してください。

一般に、-instances=static (および -pto) は使わないでください。使うメリットはすでになく、依然として、『C++ ユーザーズガイド』で説明しているデメリットがあります。

言語間リンクエラー

-xlang=f77 コマンド行オプションを使用すると、コンパイルプロセスでリンカーエラーが発生します。エラーを回避するとともに適切な実行時ライブラリをインクルードするには、代わりに -xlang=f77,f90 を使用してコンパイルします。

リンク時の名前符号化の問題

次の場合に、リンク時に問題が発生することがあります。

デバッグツールから、メンバー関数に余分な先行パラメータがあるという誤ったメッセージが返される

互換モード (-compat) では、C++ コンパイラはメンバー関数を指すポインタのリンク名を正しく符号化しません。このエラーのため、復号化プログラムおよび、dbx や c++filt などのデバッグツールから、メンバー関数に余分な先行パラメータ (メンバー関数が属しているクラスタイプを示す) があると報告されます。この問題を解決するには、-Qoption ccfe -abiopt=pmfun1 フラグを追加します。しかし、一般に、このフラグを使用してソースをコンパイルすると、このフラグなしでコンパイルしたソースとの間のバイナリレベルの互換性が失われることがあります。標準モード (デフォルトモード) では、この問題は起きません。

大域的ではない名前空間のオブジェクトをテンプレートから参照できない

プログラムでテンプレートと静的オブジェクトを使用していると、-instances=extern を指定してコンパイルした場合に未定義シンボルのリンク時エラーが発生します。これは、デフォルト設定の -instances=global では問題になりません。コンパイラは、大域的でない名前空間スコープのオブジェクトに対するテンプレートからの参照をサポートしません。次の例を考えてみましょう。

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

この例では、テンプレートクラスのメンバーは静的な名前空間スコープ変数を参照します。名前空間スコープはファイルスコープを含むことに注意してください。コンパイラは、静的な名前空間スコープ変数を参照するテンプレートクラスのメンバーをサポートしません。複数のコンパイル単位からテンプレートがインスタンス化されると、各インスタンスは異なる k を参照します。つまり、C++ 単一定義規則違反が発生し、コードは定義されていない動作を起こします。

ユーザーは、k をどのように使用するか、それによってどのような効果を得ようとするかに基づき、次に示す代替方法を実施できます。2 番目のオプションは、クラスのメンバーの関数テンプレートにのみ使用できます。

  1. 変数に外部リンケージを持たせる

                  int k; // not static 

    すべてのインスタンスは、k の同じコピーを使用します。

  2. 変数をクラスの静的メンバーにする

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

    静的なクラスメンバーは外部リンケージを持ちます。C<T>::foo のインスタンスが使用する k はそれぞれ異なります。C<T>::k のインスタンスは、ほかの関数で共有することができます。通常はこのオプションが使用されます。

名前空間内の #pragma align と符号化名

名前空間内で #pragma align を使用する場合は、符号化名を使用する必要があります。たとえば、次のコードでは、#pragma align 文は何の働きもしません。この問題を解決するには、#pragma align 文の a、b、および c を符号化された名前に変更します。

        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;
        }
関数の多重定義の解決

C++ コンパイラの従来のリリースでは、C++ 標準の要件に従って関数の多重定義の解決を行いませんでした。今回のリリースでは、多重定義された関数の呼び出しを解決して、多くのバグを修正しています。特に、コンパイラは、呼び出しが実際にあいまいな場合は関数をピッキングしたり、実際にはそうでない場合にも、呼び出しがあいまいであると表示したりする場合がありました。

あいまいであることを示すメッセージに関する回避策には、不要なものもあります。以前には報告されなかった、あいまいに関する新しいエラーが発生しています。

あいまいな関数呼び出しの主な原因の 1 つは、組み込み型のサブセットにさえも多重定義が発生することです。

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

この問題を修正するには、f1 をまったく多重定義しないか、昇格を経験しない各型、つまり int、unsigned int、long、unsigned long、double を多重定義します (long long、unsigned long long、および long double 型がある場合もあります)。

もう 1 つのあいまいに関する主な原因はクラスにおける型変換関数で、特に多重定義された演算子またはコンストラクタが存在する場合です。

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

この演算は、次のように解決できるので、あいまいです

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

多重定義された演算子または型変換関数を使用できますが、両方使用すると、あいまいと判断されます。

実際、型変換関数そのものは、あいまいと判断されたり、意図しなかった場所で変換が発生したりすることがたびたびあります。変換を有効にする必要がある場合は、型変換関数ではなく名前付き関数を使用してください。たとえば、operator int(); の代わりに int to_int(); を使用します。

この変更により、演算子 1 + t はあいまいではなくなります。T(1) + t としか解釈できません。ほかの解釈が必要な場合は、1 + t.to_int() のように記述する必要があります。

Fortran

このリリースの f95 コンパイラでは、次の問題に注意する必要があります。

従来のリリースの f95 コンパイラで生じた互換性の問題は今回のリリースのコンパイラにも継続して存在します。従来の f95 のリリースから更新を行う場合は、それらの互換性の問題に注意してください。互換性の問題とは次のとおりです。

配列組み込み関数における大域レジスタの使用

配列組み込み関数の ANY、ALL、COUNT、MAXVAL、MINVAL、SUM、PRODUCT、DOT_PRODUCT、MATMUL は、各 SPARC プラットフォームアーキテクチャー用に高度に調整されています。このため、これらの関数は大域レジスタの %g2、%g3、%g4 をスクラッチレジスタとして利用します。

上記の配列組み込み関数を呼び出す場合に、これらのレジスタが一時記憶領域として利用できることを前提にしたユーザーコードを作成しないでください。これらのレジスタ内のデータは、配列組み込み関数を呼び出したときに上書きされます。

アーカイブライブラリ内の F95 モジュールが実行可能ファイルに含まれない

デバッガ dbx では、コンパイルに使用されたすべてのオブジェクトファイルが実行可能ファイルの中に含まれている必要があります。通常、ユーザーが追加の作業を実行しなくても、プログラムはこの要件を満たしています。例外となるのは、モジュールを含むアーカイブを使用している場合です。プログラムがモジュールを使用するが、モジュール内の手順または変数をいずれも参照しない場合は、結果として生じるオブジェクトファイルには、モジュール内で定義されるシンボルへの参照は含まれません。オブジェクトファイル内で定義されているシンボルへの参照がある場合のみ、リンカーはアーカイブから取得したオブジェクトファイルをリンクします。このような参照が存在しない場合は、オブジェクトファイルは実行可能ファイルに含められません。使用されたモジュールに関連するデバッグ情報を dbx が検索しようとする場合に、dbx は警告を生成します。デバッグ情報が見つからないシンボルに関する情報は提供できません。

この問題を回避するためには、-u リンカーオプションを使用します。このオプションは、1 つのシンボルをそのオプション引数として取ります。そのシンボルを未定義のリンカーシンボルのセットに追加し、問題を解決します。モジュールと関連付けられているリンカーシンボルは通常、小文字の文字列に下線が後続するモジュール名です。

たとえば、モジュール MODULE_1 を含むオブジェクトファイルをアーカイブから取り出すには、リンカーオプション -u module_1_ を指定します。f95 コマンドを使用してリンクを実行する場合、コマンド行で -Qoption ld -umodule_1_ を使用してください。