更新日付: 2004 年 3 月 23 日

Sun[tm] Studio 9:Tools.h++ 7.1.0 Readme

 

 


注 - この Sun Studio 9 リリースでは Tools.h++ に変更はありません。 節 A から F を通して Forte Developer 7 Tools.h++ 7.1.0 Readme からの変更はありません。

目次

  1. はじめに
  2. ソフトウェアの修正事項と新機能
  3. 問題点と回避策
  4. 制限事項と互換性の問題
  5. 記述の誤りの訂正
  6. FAQ

A. はじめに

この文書は、Tools.h++ バージョン 7.1.0 についての最新情報です。記載内容は、今回のリリースで対処したソフトウェアの修正事項、既知の問題点、制限事項、互換性の問題等です。この Readme は、 Tools.h++ の 1999 年 9 月現在のバージョン 7.1.0 とそれ以前のバージョン (該当する場合は注記しています) を対象とします。

この文書のテキスト版を表示するには、コマンドプロンプトに対して次のコマンドを入力します。

    example% more /opt/SUNWspro/READMEs/ja/Tools.h++ 

この文書の HTML 版にアクセスするには、Netscape(TM) Communicator 4 または互換バージョンの Netscape ブラウザから、次のファイルを開きます。

    file:/opt/SUNWspro/docs/ja/index.html 

注 - Sun Studioソフトウェアが /opt 以外のディレクトリにインストールされている場合は、システム管理者に実際のパスをお尋ねください。

 


B. ソフトウェアの修正事項と新機能

  1. 夏時間規則を導出する新しい静的関数: RWZone::os()

    新しい静的関数 RWZone::os() は、zone.cpp に追加されています。この関数を呼び出すと、基本システムから現在の夏時間規則を導出します。 RWZone::local(RWZone::os () ) をインスタンス化すると、当年度の夏時間規則を設定します。

  2. RWXDRi(o)stream のバグ修正 (7340):XDR ストリームは IRIX 上で 64 ビットをサポートしています。

  3. RWTime bug(9194) のバグの修正:time_t から RWTime に戻しました。

  4. RWCRExpr bug(11049) のバグの修正:閉じていない括弧リストをコンパイルするときの無限ループが解決されました。

  5. RWCRExpr の問題の解決: 括弧式内の開く括弧の直後にキャレット "(^" が見つからなかった場合に無効な状態になっていました。

  6. RWCRExpr のバグの修正: 文字列内の最も長いパターンにマッチしませんでした。

  7. インデックスが無効な場合に、テンプレート化されたベクトルの removeFirst() メソッドから Boundary Error が送出されるようにしました。

  8. RWT***OrderedVector に "operator=="、また、RWT***SortedVector に "operator<" を追加して、標準 C++ ライブラリを利用しなくても、これらのクラスを再帰的にインスタンス化できるようにしました。

C. 問題点と回避策

ここでは、今回のリリースを発表する前に解決できなかった問題点とそれらの問題に対する回避策を説明します。

  1. スレッド対応バージョンのライブラリで、RWCString コンストラクタの処理速度が非常に低下します。ただし、この問題は大部分のユーザーには影響ありません。

  2. テンプレートコレクションクラスのメンバー関数のいくつかについて、T ではなく const T & を返すように変更しました。メソッド間のオブジェクトのコピーに生じるオーバーヘッドを回避できることから、この変更は成功と言えます。ただし、一部のケースで、コードが正常に機能しません。すなわち、const のデータ型に伴う問題を避けるためにオブジェクトのコピーを取り込むようにしているコードでは、現在使用している非 const メソッドが const 参照で機能しないことがあります。最良の解決方法は、正しく const されるようにコードを書き換えることです。

  3. 演算子の<<、>> を vstream と組み合わせて使用する RWBoolean およびブール型 (bool) を持続するときの問題。コンパイラが bool を「実数型」としてサポートしている場合、RW_NO_BOOL は未定義、RWBoolean はブール型に型定義されます。ただし、ブール型へのポインタの変換は標準の変換であるため、RWBoolean (bool) を vstream から抽出、または vstream に挿入する目的で演算子 >> と <<を使用している場合、たとえば、次のコードをコンパイルする場合、コンパイラは次の 2 つの違いを判断できないというメッセージを出力します。
     RWpostream::operator<<(RWBoolean) 

    (たとえば)

     operator<<(RWVostream&, const RWCollectable*) 

    次のようなコードをコンパイルする場合、

     anRWpostream << aDerivedCollectable* 

    (コンパイラが判断できない理由は、どちらの場合も、引数の一方は完全に一致するのに、もう一方は組み込み変換を必要とするため、どちらを選択しても同じ程度の妥当性があるためです。)

    この問題は、Tools.h++ の仮想ストリームを再設計することで対処できますが、このために必要な変更によって、現状のコードのリンク互換性が損なわれるため (同時に、一部ユーザーにとっては、コードの互換性さえ維持できなくなるため)、解決が先送りになっています。代替措置として、サンでは、bool 用に多重定義された挿入演算子と抽出演算子を削除しています。この制約は vstream 階層の put() メソッドおよび get() メソッドには適用されないため、多重定義された演算子を使わずに、これまでどおり RWBoolean (bool) を持続できます。

    この問題を発生させるコンパイラは、vstream にブールを挿入するとき、表示をしないでブールを他のデータ型に変換します。このため、次のようなコードも一見正しく動作します。

     aPostream << FALSE << " or " << TRUE;
    

    ただし、対応するエクストラクタは失敗します。

     aPistream>> oneRWBoolean << aString << anotherRWBoolean;
    

    さらに、このようなコンパイラの中には、このようなケースでまったく不適切な診断を下し、「oneRWBoolean と anotherRWBoolean を const int 参照に変更するように」という内容のメッセージを出力するものが少なくとも 1 つはあります。ブールを vistream から抽出するときの問題であることを示唆する診断がコンパイラから出力された場合は、抽出コード (コンパイラによって指示されている) だけでなく挿入コードにも次の修正を適用する必要があります。適用しないと、挿入バイト数が、ストリームから get() で取り出す数と一致しなくなります。具体的には、次のようにコードに書き換えます。

     aVostream << anyBoolean;
    

    上のコードを次のように書き換えます。

     aVostream.put(anyBoolean);
    

    および

     aVistream >> anyBoolean;
    

    上のコードを次のように書き換えます。

     aVistream.get(anyBoolean);
    

    これらの修正は、修正を必要とするクラスの rwSaveGuts および rwRestoreGuts の本体、 および RWCollectable から派生する独自のクラスの saveGuts および restoreGuts メソッドで行います。


D. 制限事項と互換性の問題

ここでは、各種制限事項やシステムおよび他のソフトウェアとの互換性の問題について説明しています。最新情報については、http://docs.sun.com から入手可能なリリースノートを参照してください。


E. 記述の誤りの訂正 

  1. 内部クラスの問題

    Tools.h++ による内部使用のみを目的として開発されたクラスの一部が、マニュアルの「クラス階層」に記載されていて、「クラスリファレンス」には記載されていません。それらのクラスは意図的に省略されたもので、記載されていないクラスは、将来のリリースでユーザーに通知することなく変更、拡張、削除される可能性があります。それらのクラスは使用しないでください。

  2. RWFactory

    「クラスリファレンス」で紹介されている RWFactory の使用例は誤りです。次のコード例は間違っています。

     RWBag* b = (RWBag*)getRWFactory()->create(__RWBAG);
    

    正しくは、次のようになります。

     RWBag* b = (RWBag*)rwCreateFromFactory(__RWBAG);
    
  3. RWTPtrSlistIterator

    RWTPtrSlistIterator の「クラスリファレンス」の説明に誤りがあります。正しくは、「slist を変更すると、反復子が有効でなくなります」です。これは、一般に、すべての反復子についてもいえます。

  4. テンプレート化された辞書コンテナに格納されている値

    テンプレート化された辞書コンテナに格納されている値は、operator==() および operator<() に応答しなければなりません。この機能は、規格の仕様に従って、標準 C++ ライブラリを実装クラスとして使用する場合や、同じキーであっても値の異なるコンテナが正しく区別されるよう、独自の実装を行っている場合に必要です。ANSII/ISO 規格の草稿によると、コンパイラは、これらの演算子を使用される場合のみ要求する必要があります。残念ながら、一部のコンパイラは、この規格草稿に適応していません。

  5. マニュアルの operator== に関する記述

    マニュアル内のテンプレートコレクションをインスタンス化する型の意味の説明に、「クラス K は、十分に定義された等価の意味の解釈 (K::operator==(const K&)) を持たなくてはならない」という意味の記述があります。この例は限定的すぎます。正確には、「コンパイラは、演算子の実装状態に関係なく、K の 2 つのインスタンスに適用される operator== を確実に見つけることができなくてはならない」です。

  6. RW_CENTURY_REQD

    RW_CENTURY_REQD は、"x" フォーマットの asString が西暦を 4 桁で出力するようにします。asString はデフォルトで "x" フォーマットオプションを選択するため、西暦の 4 桁表示もデフォルトになります。オペレーティングシステムが管理している他のフォーマットオプションが、この影響を受けることはありません。

  7. RWLocaleSnapshot

    RWLocaleSnapshot に関する次の説明が、マニュアルに記載されていませんでした。

    注 - RWLocaleSnapshot クラスのコンストラクタは、スレッドに対して安全ではない setlocale 関数を呼び出します。マルチスレッド環境で問題が起きないようにするには、他のどのスレッドもロケール依存関数を使用しないことが保証できるときにだけ、RWLocaleSnapshot のインスタンスを作成してください。この条件を保証するために、初期スレッドで RWLocaleSnapshot のすべてのインスタンスを作成してから、その他のスレッドを起動します。新しい情報は、現時点ではありません。


F. FAQ

  1. Rogue Wave Software と連絡を取りたいのですが。

    Rogue Wave からサン製品のサポートを受けることはできません。その他の Rogue Wave 製品に関する情報は、次のどちらかの電話番号に電話してください。

    1-541-754-3010 または
    1-800-487-3217

  2. Tools.h++ のサポートを受けたいのですが。

    その他のサン製品同様、サンのサポートをご利用ください。 サンは、Rogue Wave からアップデートやコンサルティングサービス、修正を受けていますが、Tools.h++ を完全にサポートしています。

  3. サンのバージョンと Rogue Wave のバージョンは別ですか。

    Tools.h++ のサンと Rogue Wave のバージョンは、同じソースをもとに作成されています。問題の修正はマスターソースにも反映されます。ただし、それぞれ独自のスケジュールでリリースしているため、リリースされたバージョンには若干の相違があることがあります。一般に、より頻繁にリリースされるため、常にというわけではありませんが、Rogue Wave の方がサンよりバージョンが少し進んでいることがあります。

    サンではマイナーリリース全般にわたってリンク互換性を維持していて、特定の修正がリンク互換性に影響を与える場合は、修正を控えることがあります。 リンク互換性を維持することによって、新しい Tools.h++ ライブラリを旧 Tools.h++ ライブラリでコンパイルしたオブジェクトファイルにリンクできます。

  4. 最新の Rogue Wave バージョンをサンから入手できますか。

    サンが最新の Rogue Wave バージョンを同時出荷する場合を除き、通常はできません。重大なプログラム修正があった場合、サンから同時期に入手できることもあります。

  5. Tools.h++ ヘッダーファイルはどこにありますか。
     example% CC -H <ファイル>.cc
    を使用して、インストールディレクトリ内の Tools.h++ ヘッダーファイルの格納場所を確認できます。

  6. libwtool の共有ライブラリ版はありますか。

    Tools.h++ 7 用の共有ライブラリ版があります。

  7. Tools.h++ を利用するライブラリを構築しても問題ありませんか。

    作成手順を簡単にするなどの目的で、Tools.h++ に依存するアーカイブライブラリをプロジェクト内で内部的に構築することは、まったく問題がありません。自分のアーカイブ ライブラリを他のユーザーに渡す場合は、そのユーザーも Tools.h++ の正規ユーザーである必要があります。サン製品の顧客は librwtool.so.2 を再頒布できますが、付属するヘッダーファイルは頒布できません。

    詳細は、<install-directory>/READMEs/ja/runtime.libraries を参照してください。

  8. dbx から RWCString を出力するには、どうしたらいいですか。

    Sun WorkShop では、dbx のコマンドインタプリタは Korn シェルです。このため、特化したデバッグ機能を持つ新しい dbx コマンドを定義できます。文字列の出力はよく必要とされる機能です。dbx で文字列を出力する方法については、Tools.h++ マニュアルのコンパイルとデバッグに関する章を参照してください。RWCString を出力するもう 1 つの方法として、次のような新しい dbx コマンドを定義することもできます。

     function dumpstr { print (char*)($1.pref_+1) } 

    この関数があると dbx で次の定義が実行できます。

     (dbx) dumpstr myString (char *) (myString.pref_+1) = 0x28d5c "Contents of myString" (dbx) 

    dumpstr の定義を .dbxrc に書き込むこともできます。

  9. その他の注意事項
    • RWCString と RWWString のサイズは、clone メンバー関数を使用して変更できます。aString.clone(0) を使用すると、String のサイズがちょうど十分な大きさになるように調整されますが、aString.clone(aString.length()+someMore) 使用すると、someMore で指定したバイト数の領域がバッファ内に余分に確保されます。全反復子共通:コレクションを直接変更するか、関係する反復子以外のすべての反復子を使用して変更した場合、その反復子の有効性は保証されなくなります。「大体の場合」はこのような副作用なしに変更できるコレクションもありますが、コレクションの変更後も反復子が信頼できることを全面的に期待すると、予想外の問題が発生する可能性があります。ご注意ください。

    • 一部のテンプレート化されたコンテナには、clearAndDestroy() メソッドがありますが、このメソッドにはコンテナが同一オブジェクトへのポインタを複数保持してしまうことへの保護機構が組み込まれていません。コンテナが重複したポインタを保持している可能性がある場合は、clearAndDestroy() は呼び出さないでください。(RWCollections には当てはまりません。)

    • 一部の Tools.h++ メソッドは多重定義されて、ポインタ型と整数型のどちらでも受け取れるようになっています。たとえば、RWTime コンストラクタには、構造体へのポインタ (struct tm* ) と、「時間の始まり」以降の秒数を表す整数値 (unsigned long) のどちらでも渡すことができます。このようなメソッドにゼロを渡そうとすると、コンパイラは正しく「あいまいさ」であることを示すメッセージを返します。 この問題は、ゼロ値を適切なデータ型の変数に格納するか、キャスト (型変換) するか、"0ul" などのように定数の型を明示的に指定することによって解決できます。

    • struct tm* からの不正な RWTime の作成の問題:システム関数 localtime() は static struct tm へのポインタを返します。その後さらに localtime を呼び出すと、この構造体が上書きされます。RWTime は RWZone::local() が必要になると作成します。この作成でも localtime() が呼び出されます。localtime() の呼び出しに関連する問題が生じた場合は、localtime() を最初に呼び出す前に RWZone::local() への呼び出しを行なってください。

    • RWLocale::asString(struct tm*, ..%U.., RWZone&= RWZone::local()) は、日曜日から始まる年の第何週かを示す値について、プラットフォームによって異なる値を返します。標準は存在しますが、多くの実装が準拠していません。Rogue Wave は結果を検査しないで、そのまま渡すため、プラットフォーム間の結果の相違が問題になる場合は、%U 書式指定子を使用しないでください。

    • RWFactory の使用と多相持続性の問題:ファクトリ (Factory) によって RWCollectable を作成するには、その前にそのコレクタブル (Collectable) とその識別子が登録されている必要があります。このためには、プログラムの中で、その RWCollectable のインスタンスを少なくとも 1 つ作成します。

      この問題はさまざまな形で現れます。通常は次のメッセージが表示されます。

      "[NOCREATE] RWFactory: no create function for class with ID (something)"

      ただし、場合によっては theFactory->create(someID) の呼び出し時にコアダンプや GPF が発生する可能性もあります (この呼び出しは、持続性がある RWCollectable の読み取り中に行われます)。この現象は、オブジェクトへのポインタだけをインスタンス化した場合に、そのオブジェクトそのもののインスタンスを作成しないコンパイラで、発生することがあります。

    • 独自の RWCollectable を作成するときは、その独自クラスに、RWCollectable メソッドが使用するすべてのメソッドを用意することが重要です。特に、持続性機構が「満たす」ことができる新しい「空の」インスタンスを作成するためのデフォルトのコンストラクタと、オブジェクトのコピーを新しい場所に作成するためのコピーコンストラクタを用意する必要があります。また、関連のあるメソッドと演算子が互いに矛盾しないよう注意する必要もあります。たとえば、そのクラスに比較演算子を定義する場合は、それらの演算子から、compareTo() が返す値と一致する結果が返されるようにします。

    • RWCollectable::recursiveStoreSize() と RWCollectable::binaryStoreSize() を使用するタイミング:答えは単純ですが、若干の考慮が必要になることがあります。 operator<<() 、またはマニュアルに記載されていない recursiveSaveOn() メソッドを使用する場合は、RWCollectable の「一番上の」レベルで recursiveStoreSize() を使用すべきです。これに対し、binaryStoreSize() は、コレクション全体の「一部」を操作する場合 (つまり、saveGuts() を使用する場合) に使用します。

      どちらのメソッドもストリームの操作は行いません。両方とも RWFile に対してのみ使用可能です。仮想ストリームに保存された形の RWCollectable のサイズを調べる場合は、クラス RWAuditStreamBuffer を使用してください。

    • メインの前に相互排他ロックを使用すると、静的初期化の順序を知ることが困難であること (一般的な解決策なし) と、特定の相互排他ロックをメインの前のどのスレッドが初期化すべきかを知ることが困難であるという対の問題が発生します。 現在のところ、この問題に対するソフトウェアによる解決方法はありません。このため、静的初期化コードを使用して「スレッド活用」関数を呼び出すのは避けてください。

    • 独自クラスにおけるテンプレート化されたハッシュベースのコンテナの使用:デフォルトでないコンストラクタ (たとえば、Tools.h++ のハッシュベースコンテナ) を必要とするクラスメンバーをユーザー独自のクラスに追加する方法について、多くのユーザーから問い合わせがありました。このためには、「メンバー初期化」と呼ばれる特殊な構文を使用してください。たとえば、次のハッシュ辞書メンバーが独自クラスに存在すると仮定します。

        class MyClass {
          // ...
          RWTValHashDictionary<RWCString,int> myDict; // no ctor args here!
       public:
       MyClass();
       };
      

      メンバの初期設定は次のようになります:
      実際のコンストラクタの本体を提供する場所では ":" を使用する必要があります。その後、デフォルト以外のコンストラクションを必要とする各メンバのコンストラクタをコンマで区切ったリストを配置します。次の例は上記の例に基づいています。

       MyClass::MyClass() :myDict(theHashFunction) /* このように指定 */ { /* 独自のコンストラクタ用のコード */ } 

      もちろん、ケースによっては、この代わりにメンバー初期化構文を使用してインラインのコンストラクタを書くこともできます。ただし、クラス宣言内の辞書の「宣言」にコンストラクタ引数を追加することはできません。

 


Copyright (C) 2004 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms.