6

それは単純に見える質問です:

ネイティブ サイズの整数が算術演算に最適であるとすれば、C# (または他の .NET 言語) がネイティブ サイズのIntPtrandを使用した算術演算をサポートしないのはなぜUIntPtrですか?

理想的には、次のようなコードを記述できます。

for (IntPtr i = 1; i < arr.Length; i += 2) //arr.Length should also return IntPtr
{
    arr[i - 1] += arr[i]; //something random like this
}

32 ビットと 64 ビットの両方のプラットフォームで動作するようにします。(現在、 を使用する必要がありますlong。)


編集:

私はこれらをポインターとして使用していません(「ポインター」という言葉は言及されていませんでした)。native intこれらは、MSIL およびintptr_tCの C# の対応物として扱うことができます。これらはポインターではなくstdint.h整数です。

4

5 に答える 5

6

おそらく、ネイティブ サイズの整数は演算を最速にしますが、エラーのないプログラムを実現できるわけではありません。

個人的には、座って入力を始めるときにサイズがわからない整数型を使用したプログラミングは嫌いです (C++ のことを考えています)。プラットフォームに合わせて調整された CPU 命令を使用すると、条件付きでパフォーマンスが向上する可能性があります。

この情報にアクセスせずにマシンコードを生成する必要がある「通常の」コンパイラとは対照的に、JITコンパイラはプロセスが実行されているアーキテクチャに合わせて最適化できることも考慮してください。したがって、JIT コンパイラーはより多くのことを知っているため、同じくらい速くコードを生成する可能性があります。

これを考えているのは私だけではないと思うので、それには理由があるかもしれません.

于 2011-04-08T03:03:20.073 に答える
6

.NET 4 では、型の左側のオペランドと整数型 ( 、 など) の右側のオペランドの間の演算がサポートIntPtrています。intlong

[編集]: 他の人が言ったように、ネイティブ言語でポインターを表すように設計されています (IntPtr という名前が示すように)。それらをポインターではなくネイティブ整数として使用していると主張しても問題ありませんが、整数のネイティブ サイズが重要になる主な理由の 1 つは、ポインターとして使用するためであることを見逃してはなりません。コードが実行されているプロセッサやメモリ アーキテクチャから独立した数学演算やその他の一般的な関数を実行している場合は、固定サイズと上限がわかっているintなどの型を使用する方が間違いなく便利で直感的です。longハードウェアに関係なく、あらゆる状況で下限。

IntPtrがネイティブ ポインターを表すように設計されているのと同様に、算術演算は、ポインターに対して実行する論理的な数学演算を表すように設計されています。ネイティブ ポインターに整数オフセットを追加して、新しいネイティブ ポインターに到達します (2 つIntPtrの sを追加することではありません)。はサポートされておらずIntPtr、右側のオペランドとしても使用されていません)。

于 2011-04-08T02:55:22.000 に答える
1

IntPtr(またはUIntPtr)が役立つ理由の1つを実際に考えることができます。配列の要素にアクセスするには、ネイティブサイズの整数が必要です。ネイティブ整数はプログラマーに公開されることはありませんが、ILでは内部的に使用されます。C#のようなものは、実際にはILでsome_array[index]コンパイルされます。ILSpyで自分のsome_array[(int)checked((IntPtr)index)]コードを逆アセンブルした後、これに気づきました。(私のコードでは変数は64ビットです。)逆アセンブラが間違いを犯していないことを確認するために、Microsoft独自のILDASMツールはindexconv.uconv.i私のアセンブリ内の指示。これらの命令は、整数をシステムのネイティブ表現に変換します。これらすべての変換命令がILコードに含まれていることがパフォーマンスにどのような影響を与えるかはわかりませんが、JITがパフォーマンスの低下を最適化するのに十分賢いことを願っています。そうでない場合、次善の策は、変換なしでネイティブ整数を操作できるようにすることです(これは、私の意見では、ネイティブ型を使用する主な動機になる可能性があります)。

現在、F#言語では、nativeintとの符号なしの対応物を算術演算に使用できます。ただし、配列はintF#でのみインデックスを作成できnativeintます。つまり、配列のインデックスを作成する目的にはあまり役立ちません。

本当に気になる場合は、ネイティブ整数の使用に関する制限を解除する独自のコンパイラを作成するか、独自の言語を作成するか、ILでコードを作成するか、コンパイル後にILを微調整します。個人的には、ネイティブintを使用して余分なパフォーマンスを絞り出したり、メモリを節約したりするのは悪い考えだと思います。コードを手袋のようにシステムに適合させたい場合は、プロセッサ組み込み関数をサポートする低水準言語を使用するのが最善です。

于 2012-05-27T07:08:37.067 に答える
0

.Net Frameworkは、説明できない操作を導入しないようにしています。つまり、2つの日付の合計などの概念がないため、DateTime+DateTimeはありません。同じ理由がポインタタイプにも当てはまります。2つのポインタの合計という概念はありません。IntPtrがプラットフォームに依存するint値として格納されるという事実は、実際には重要ではありません。基本値として内部的に格納される他のタイプがたくさんあります(ここでも、DateTimeはlongとして表すことができます)。

于 2011-04-08T04:16:50.473 に答える
-1

それは、メモリアドレス指定を処理する「安全な」方法ではないためです。ポインター演算は、C# が明示的に回避するように設計されている、あらゆる種類のバグやメモリ アドレッシングの問題を引き起こす可能性があります。

于 2011-04-08T02:50:05.397 に答える