質問: (double *)pc; こちらは、「明示的にキャストが行われています」(多分) 1、この2つ(明示的キャスト、暗黙的キャスト)正直何が違うんですか?? 明示的にキャストする場合としなくても良い場合の違いがわかりません。C/C++でも違いがあるそうですが・・・ 2、アライメントを考慮すると「暗黙的、明示的関係なく、ポインタを別の型のポインタへのキャストする」のは控えた方がよろしいんですかね??? 3、この実験コードに修正箇所があれば、教えてください。 [追記] 実験したのはwindowsです。 visual studioでオプションは何も入れないで、clコンパイルしています。 [追記2] 私のC言語の本にこう書いてあります。 > > ポインタを他の型へのポインタに型変換することは、その値までもが変わる可能性のある危険な行為であり、注意深く行わなければならない。型や型変換に対して厳密なC++が、voidへのポインタを別の型のポインタに代入する局面で明示的なキャストを必須としているのは、このような危険を避けるためです。 > > > えーーーと 明示的なキャストすることで、どうしてポインタを他の型へのポインタに変換する際の危険性を避けることができるのでしょうか??
回答: 「暗黙的にキャストが行われている」と表現されてますが、コンパイルすると「互換性のないポインターだよ」とコンパイラーが警告を発すると思います。 型が違うポインターどうしての代入などの演算はプログラマーになんらかの意図があるはずであり、質問者さんがおっしゃる「暗黙的キャスト」は避けるべきコーディングです。そのまま警告を放置するなら何かが起こるのでしょうがそれを気にすること自体はあまり有意義なことではないと思います。 char*->double*への明示的なキャストについて考えてみますと「double型のアドレスとして妥当なアラインメントであるかをプログラマーが意識した上で敢てキャストする」と考えるのが普通だと思います。ではわざとアラインメントがおかしなキャストをしたとしたらどうなるかですが、現在のclangの規格で何か規定があるのかどうか自分は知りません。 手元のcygwin64でgcc使ってやってみるとアラインメントが適切でないポインターがdouble*変数へそのまま代入されてました。この状態で何がおこるかは自分が知る限りプロセッサの種類によって異なり、アラインメント例外を発するプロセッサと、いわれたとおりに動いてしまうプロセッサに大別されると思います。例えばインテルのプロセッサは後者だったと思います。ただ記憶装置(メモリー)は語境界でアクセスする前提で作られているのでプロセッサがアライメント境界をまたぐメモリーアクセスを許す場合、メモリーのアクセスが2回行われてプロセッサー内部で前半分と後ろ半分のデータをガッチャンとビット連結して結果を作る動作をするので「遅い」と思います。 いずれにせよアラインメントについて普通でないことをするとしたらプロセッサーとコンパイラーの動作をよく把握して何か特別な意図(あまり思い浮かびませんが)でやらない限り一般的には避けるべきコードであると言えましょう。