新しいWin64ビット モダンC++ツールチェーンは標準規格に準拠しております。しかも、大規模で複雑なライブラリのコンパイルにも非常に優れています!
Table of Contents
刷新する背景: 新しいRTL, 古いTurbo C
エンバカデロでは、アップグレードに取り組んだ際、技術的な問題に対して多くの選択を行いました。そのうちの1つは、新しいツールチェーンが使用するランタイムライブラリ(RTL)に関するものでした。RTLは、他のあらゆるプログラムの基盤となるコードを提供しています。RTLには2つの種類があり、C RTLは標準C関数(printfなど)、C++ RTLはC++例外処理などを備えています。
さらに、STL(コンテナとアルゴリズムの標準ライブラリ)とお客様自身のコードを含めると、その両方で RTL が提供するすべてのメソッドと機能が使用されます。RTLは、見落とされがちですが、アプリケーションが依存する基盤となるコードを提供していると考えることができます。
エンバカデロの古いC++ツールチェーンにはカスタムRTLが含まれており、これらを引き続き使用するか、新しいものを使用するか、決断しなければなりませんでした。
C RTLについては、WindowsがデフォルトでUCRTを提供しているという事実を考慮しました。システムが提供する標準RTLを使用できるのに、カスタム RTL を使用する必要はありません。 実際、ほぼすべてのWindowsアプリケーションがUCRTを使用しております。Windows標準として提供されている恩恵が非常に大きく、システムコンポーネントとして安全かつセキュアに更新でき、その上特にメンテナンスの必要もありません。
注:このC RTL (Windows コンポーネント) は Microsoft社によって作成されています。 いくつかの Cメソッドでは、パラメータの順序が逆になっていることがありました。 非常に低レベルの Cコードを自身で書いている場合は、メソッドの仕様を Google で検索するか、宣言とパラメータを比較してください。
C++ RTLについては、オープンソースのコードとエンバカデロ独自に作成したコードを基に、新しいライブラリを構築しました。これにより、古いツールチェーンのランタイム ライブラリの多くの問題が解決され、改めて新しいツールチェーンで例外処理が非常に優れていることを考えさせられる理由の1つになりました。(新しくコードを書き直し、それに併せて数千ものテストを行いましたが、新しいツールチェーンの例外処理で様々な問題をキャッチアップでき、結果的にコードの刷新が正しかったと考えます)。
非常に古いコードベースのプロジェクトからマイグレーションする場合、一部のメソッドで影響する可能性があります。
影響度
1980年代後半から1990年代前半にかけて、C/C++の標準化された方法を使用したコードがどれくらい存在するのか、エンバカデロでは十分に把握していませんでした。それはおそらく皆さんも同じでしょう。なぜなら、今までそれらのコードは再コンパイルすれば動作していたので、あえて実際にコードの中身までチェックしなければ、その存在すら知らなかった可能性が考えられるからです。
幸いなことに、実際にはこのような報告はほとんどありません。こちらで知る限り、最もよくあるメソッドの欠落例を 3 件報告いただきましたが、アップグレードした開発者の全体数から考えると非常に少なく、報告いただいた問題も開発者側で対処が可能です。
しかしながら、古いプロジェクトコードをお持ちで、その影響を心配されている方もいらっしゃるかもしれませんので、予想される点とその修正方法についてご説明いたします。
皆さんのコードにも影響するの?
C++Builder 12.2で新しいプラットフォームに切り替えて再構築すると、メソッドが見つからないというコンパイラエラーが発生する場合があります。「C++Builderの前のバージョンでは問題なかったのに、何故だろう?」と考えるかもしれません。
もしエラーが表示された場合は、「C++ [メソッド名]」を Google 等の検索エンジンで探して見てください。おそらく、まったく同じではないが類似したメソッドに該当する情報が得られると思います。
これらの情報は、C++に公式バージョンが存在する以前の標準化されていないC++のメソッドであるというヒントになります。
修正
幸いなことに、エンバカデロで知る限り、どのケースも簡単に修正できます。該当するメソッドは、当時標準的な方法が存在しなかったためですが、C++が標準化された際に、これらのメソッドのバージョンが作成されました。
例えば、 Google 等の検索エンジンで「C++ randomize」というキーワードで探してみてください。randomize()は乱数発生器を初期化しますが、使用されている箇所では、random(max)をstd::rand() % maxに置き換えることができます。(ご自身のコードで正しいかどうか確認してください。)
上記のように標準化される前の古いメソッドを使用してコードを書いている方はほとんど見かけなくなりましたが、ほとんどのコードが何度もアップグレードおよび改訂されて該当する古いメソッドが削除されたためなのか、アップグレードした開発者が古いメソッドを簡単に置き換えることができるため、単にエンバカデロへ報告されていないだけかもしれません。
もし同様な問題を見つけた場合は、以下の方法でご連絡ください。
- Embarcadero Quality Portalへ報告
- エンバカデロのサポートへ報告 (アップデートサブスクリプションをお持ちの方)
エンバカデロでは、古い RTL 領域のバージョンを公開することでアップグレードを支援する「shim」ライブラリの作成を検討していますが、アップグレードの数に比べると報告の数が少ないため、それが価値のあることなのか正直なところ分かりません。もし皆さんが遭遇した問題があれば、ご連絡ください。
ウェビナーについて
本ブログの内容は、エンバカデロのC++のブロダクトマネージャである「David Millington」が、ウェビナー内で「Tip #2, Handling Old RTL」という節でフル尺で解説しています。このウェビナーはC++Builder / RAD Studio 12.2の新しいWin64 モダンツールチェインを活用するためのヒントや非常に有益な情報を紹介しています。もしウェビナー(英語)をご覧になりたい場合は、以下をご参照ください。
「Tip #2, Handling Old RTL」の節は、下記の動画の「1:01:02〜」です。