C ++コードで管理する必要があるものを管理する(つまり、「CLR互換」にする)コンパイラを作成できないのはなぜですか?
状況によってはvoidポインタを禁止するなど、ある程度の妥協が必要かもしれません。しかし、これらすべての余分なキーワードなど。これらの追加によって解決する必要のある問題は何ですか。
私はいくつかの側面と解決するのが難しいかもしれないことについて私の考えを持っていますが、良いしっかりした説明をいただければ幸いです!
C ++コードで管理する必要があるものを管理する(つまり、「CLR互換」にする)コンパイラを作成できないのはなぜですか?
状況によってはvoidポインタを禁止するなど、ある程度の妥協が必要かもしれません。しかし、これらすべての余分なキーワードなど。これらの追加によって解決する必要のある問題は何ですか。
私はいくつかの側面と解決するのが難しいかもしれないことについて私の考えを持っていますが、良いしっかりした説明をいただければ幸いです!
私はこれまでのところ答えに反対しなければならないでしょう。
理解すべき主な問題は、C++コンパイラが非常にダムな環境に適したコードを作成することです。最新のCPUでさえ、仮想関数については知りません。地獄、関数でさえも一筋縄ではいきません。たとえば、CPUは、スタックをアンワインドするための例外処理コードが関数の外部にあることを実際には気にしません。CPUは、ジャンプとリターンを伴う命令シーケンスを処理します。CPUに関する限り、関数には確かに名前がありません。
したがって、関数の概念をサポートするために必要なものはすべて、コンパイラーによってそこに置かれます。たとえば、vtablesは、CPUの観点から適切な値を持つ、適切なサイズの配列です。__func__
文字列テーブルのバイトシーケンスとして終了し、最後のバイトは00です。
さて、ターゲット環境がばかげている必要があると言うことは何もありません。あなたは間違いなくJVMをターゲットにすることができます。繰り返しになりますが、コンパイラーは、ネイティブに提供されていないものを入力する必要があります。生の記憶はありませんか?次に、大きなバイト配列を割り当てて、代わりに使用します。生のポインタはありませんか?そのビッグバイト配列に整数インデックスを使用するだけです。
主な問題は、C++プログラムがホスティング環境からはまったく認識できないように見えることです。JVMは馬鹿ではなく、関数については知っていますが、それらがクラスメンバーであることを期待しています。それは彼らが彼らの名前を持っ<
ていることを期待していません。>
これを回避することはできますが、最終的には名前のマングリングになります。そして、今日の名前マングリングとは異なり、この種の名前マングリングは、Cリンカーではなく、スマート環境を対象としています。そのため、そのリフレクションエンジンは、c__plus__plus
メンバー関数を持つクラスがあると確信するようになる可能性がありますが__namespace_std__for_each__arguments_int_pointer_int_pointer_function_address
、それでも良い例です。std::map
イテレータを逆にする文字列がある場合にどうなるか知りたくありません。
一般的に、逆の方が実際にははるかに簡単です。他の言語のほとんどすべての抽象化は、C++でマッサージすることができます。ガベージコレクション?これは今日のC++ですでに許可されているので、。でもサポートできますvoid*
。
私がまだ取り上げていないことの1つは、パフォーマンスです。大きなバイト配列で生のメモリをエミュレートしますか?特にダブルスを入れた場合、それは速くはなりません。あなたはそれをより速くするためにたくさんのトリックをすることができます、しかしどの価格で?あなたはおそらく商業的に実行可能な製品を手に入れるつもりはないでしょう。実際、C ++の最悪の部分(多くの異常な実装依存の動作)とVMの最悪の部分(遅い)を組み合わせた言語を思いつくかもしれません。
既存の正しいコード、つまりC ++標準に従って記述されたコードは、その動作を誤って変更してはなりません。
さて、C ++ / CLIは主に、マネージドコードとアンマネージドコードの間の接着剤となることを目的としています。そのため、管理されていない概念をマンガ化して混合する機能が必要です。同じコードで管理対象オブジェクトと非管理対象オブジェクトを割り当てることができる必要があるため、個別のキーワードを回避する方法はありません。
CLRをターゲットとするネイティブC++コードをコンパイルできないのはなぜですか?
はい、あなたはそれを正しく推測しました、あまりにも多くの妥協があり、それはそれを役に立たなくするでしょう。例を3つだけ挙げたいと思います...
1.)テンプレート:C ++はそれらをサポートしますが、CLRはサポートしません(ジェネリックは異なります)。そのため、コードでSTLやブーストなどを使用できませんでした。
2.)多重継承:CLIではなくC++でサポートされます。istreamとostreamの両方から継承する標準のiostreamクラスと派生物(stringstream、fstreamなど)を使用することさえできませんでした。
そこにあるコードはほとんどコンパイルされず、標準ライブラリを実装することさえできませんでした。
3.)ガベージコレクション:ほとんどのC ++アプリは、メモリを手動で管理します(スマートポインターなどを使用)。CLRには自動メモリ管理があります。したがって、C ++スタイルの「new」および「delete」は「gcnew」と互換性がなく、既存のC++コードはこの新しいコンパイラでは役に立たなくなります。
標準ライブラリも含めてすべての重要な機能を根絶する必要があり、既存のコードがコンパイルされない場合...それでは、ポイントは何ですか?
まず第一に、「シンプルC++」と「マネージC++」の区別は意図的なものでした。MC++の目的の1つは、既存のC++コードとCLRの間のブリッジを提供することだったからです。
次に、CLRモデルに適合しないC++機能が多すぎます。多重継承、テンプレート、ポインター演算...明確な線を引かないと、プログラマーはコンパイル時と実行時の両方で不可解なエラーに直面する運命にあります。
これは、マネージコード機能をC ++に追加すると、C ++の速度が低下し、コンパイラがより複雑になるためだと思います。そもそもC++が設計されたものを失うほどです。C ++の優れた点の1つは、操作に適した言語であり、十分に低レベルでありながら、ある程度移植性があることです。そして、おそらくそれが、C++標準委員会がそれをそのままにしておくことを計画していることです。とにかく、C ++で完全に「管理」できるとは思いません。これは、C++で記述されたプログラムを実行するにはVMが必要になるためです。その場合は、C ++/CLIを使用しないのはなぜですか。
Qtフレームワークはほとんどそれを行います。つまり、スマートポインターがあり、それらが指すオブジェクトが破棄されると、自動的にnullに設定されます。それでも、moc(メタオブジェクトコンパイラ)によって解析された後は、ネイティブC++です。
はい、C++が管理されるようになる可能性があると思います。ただし、.NETはC ++用に書き直す必要があり、BASICに偏ることはありません。多くの言語がすべて同じ屋根の下にあります。特定の機能を実行する必要があります。これはVB.NETまたはC++。NETのいずれかを選択し、VB.NETが選択されました。面白いことに、C#はVB.NETよりも人気があります(どちらも使用していませんが)。
.NET CLRでは、オブジェクトが固定されている場合を除いて、ランタイムが認識していない場所に管理対象オブジェクトへの参照が存在しないようにする必要があります。良好なパフォーマンスを得るには、オブジェクトの固定をできるだけ少なくする必要があります。.NET CLRは、C ++内で使用可能なすべてのデータ構造を理解できるわけではないため、管理対象オブジェクトへの参照がそのような構造に永続化されないようにする必要があります。「通常の」C++コードがC++言語を変更せずに.NETコードと相互作用することは可能ですが、C++コードが任意の.NETオブジェクトへのあらゆる種類の「参照」を保持できる唯一の方法は.NET側のコードは、各オブジェクトに何らかのハンドルを割り当て、ハンドルに関連付けられたオブジェクトの静的テーブルを保持します。オブジェクトを操作したいC++コードは、ハンドルで識別されるオブジェクトに対して何らかの操作を実行するように.NETラッパーに要求する必要があります。新しい構文を追加すると、コンパイラは.NET Frameworkが認識する必要のあるオブジェクトの種類を識別し、それらに必要な制限を適用することができます。
c++
最初に考慮すべきことは、 「高速」にするすべてのものが消えることです。C++の完全なガベージコレクションシステムはほぼ不可能です。コード内のほぼどこにでもポインタを置くことc++
ができるからです。実行時型情報は、それ自体が言語システムに直接組み込まれていない場合、コストがかかります。真のネイティブパフォーマンスを利用できます。テンプレートが消えます。真のポインタは消えます。メモリへの直接アクセスはなくなりました。
強制する必要があるもののリスト
1. no direct pointers(pointers will get replace with complex refernces)
2. templates (generics pay for preformance)
3. simple c-style arrays (will get wrapped with array structures)
4. programmer no longer has control of whether data is on the stack or
the heap.
5. garbage collection will be enforced(this will cause the most changes to the syntax)
6. runtime type data will get added extensively to the code.
(larger code size)
7. inlining will become more difficult for the compiler
(no more inline key word)
8. no more inline assembly.
9. the new langauge by now will become incompatible c code.(unless you go through hoops)
私は5hammerに同意します!Javaやその他の管理対象言語をそのままにしておくと、コンピューターを完全に制御し、メモリにアクセスしてメモリを管理し、コンピューターがコードを実行する方法を制御し、Cライブラリ(Luaなど)と統合する必要があります。その柔軟性を失うと、C ++を離れてCにフォールバックし、Cも管理されるようになると、アセンブラーに移動します。
マネージド言語は、ハードウェアに直接アクセスできないサンドボックスのようなものに縛られており、コンパイルされた言語よりもはるかに遅いため、すべてのゲームプラットフォーム/複雑なプログラムにとってこれまでで最悪のものです。
C ++の主な目的は、常にパフォーマンスでした。これは、ビッグゲームに最適な言語の1つです。そして、この言語パフォーマンスがなければ、多くのゲームは存在しなかったでしょう!