たとえば、次のコードを C++ で書いているかどうかは誰にもわかりません。
int a;
void *ptr = &a;
ptr = (char *)ptr + 1; //<-- this is the interesting line;
(char *)
この変数のアドレス指定方法をコンパイラに伝えるのはだけですか?
それとも、実際に実行時にさらに計算を追加しますか?
ありがとう。
この場合、追加の計算は行われません。
ただし、キャストが技術的には変換である場合があり、主に数値入力を使用します。たとえば、次の例ではランタイム コードを導入できます (最適化されていない場合、このような小さな例では最適化されていると予想されます)。
int x = 42;
double d = (double)x;
ここで、int と double の内部表現は、コンパイラが変数を認識する方法を変更するだけではなく、データも変更する必要があることを意味します。
ここでは、純粋にコンパイル時のキャストです。
一般的なケースでは、C スタイルのキャストにより、たとえば変数を縮小/拡大する必要がある場合などに、1 つまたは 2 つの命令が追加される可能性がありますが、これはまれであり、パフォーマンスに正確に影響を与えるわけではありません。
私が知っているランタイム キャストはdynamic_cast
.
特定の例では、コンパイラをバイパスするだけです。あなたは基本的に「これはではないことを知っていますchar*
が、私が何をしているのかは知っています、私を信じてください」と言っています。
ただし、ユーザー定義型を使用している場合は、キャスト演算子をオーバーロードすると、指示された操作が実行されます。
struct A
{
char* x;
A() : x("abc") {}
operator char() { return x[0]; }
operator char*() { return x; }
};
int main()
{
A a;
char x = (char)a; // x == 'a'
char* y = (char*)a; // y == "abc"
return 0;
}
それはキャストによって異なりますが、Cについては少し不満があります。むしろ、あるタイプを別のタイプに変換し、メモリのブロックを特定のタイプであるかのように扱うための別個のメカニズムがあったほうがいいです。
ただし、ポインタの場合、これは常にコンパイル時のものにすぎません。Achar*
はaとまったく同じ表現を持っているのでvoid*
(それらは単なるメモリアドレスです)、それらを変換するために何もする必要はありません。