TL;DR
int *sieve = (int *) malloc(sizeof(int) * length);
には 2 つの問題があります。キャストと、変数の代わりに型を sizeof の引数として使用していること。代わりに、次のようにします:
int *sieve = malloc(sizeof *sieve * length);
ロングバージョン
いいえ;あなたはしない 結果をキャストします:
void *
のように不要です この場合、他のポインタ型に自動的かつ安全に昇格されます。- コードが煩雑になり、キャストが読みにくくなります (特にポインター型が長い場合)。
- 繰り返しになりますが、これは一般的に悪いことです。
<stdlib.h>
を含めるのを忘れた場合、エラーを隠すことができます .これにより、クラッシュが発生する可能性があります (または、さらに悪いことに、発生しません) コードのまったく別の部分でかなり後までクラッシュを引き起こします)。ポインターと整数のサイズが異なるとどうなるかを考えてみましょう。キャストによって警告を隠しているため、返されたアドレスの一部が失われる可能性があります。注:C99 以降、暗黙の関数は C から削除されました。宣言されていない関数がint
を返すという自動的な仮定がないため、この点はもはや関係ありません。 .
明確にするために、「キャストしない」と言ったのは「必要ない」ではなく、 私の意見では、キャストを正しく行ったとしても、キャストを含めるのは失敗です。それを行うメリットはまったくありませんが、多くの潜在的なリスクがあり、キャストを含めることはあなたが知らないことを示していますリスクについて
また、コメンテーターが指摘しているように、上記は C++ ではなくストレート C について述べていることに注意してください。私は、C と C++ は別の言語であると固く信じています。
さらに追加するには、コードで型情報を不必要に繰り返します (int
) エラーが発生する可能性があります。戻り値を格納するために使用されているポインターを逆参照して、2 つを一緒に "ロック" することをお勧めします:
int *sieve = malloc(length * sizeof *sieve);
これは length
も移動します 視認性を高めるために前面に配置し、sizeof
で冗長な括弧を削除します; 必要なだけ 引数が型名の場合。多くの人はこれを知らない (または無視している) ようで、コードが冗長になります。覚えておいてください:sizeof
は関数ではありません! :)
length
移動中 可能性があります いくつかのまれなケースで可視性を向上させますが、一般的なケースでは式を次のように書く方がよいことに注意する必要があります:
int *sieve = malloc(sizeof *sieve * length);
sizeof
を維持してから まず、この場合、乗算が少なくとも size_t
で行われることを保証します 数学。
比較:malloc(sizeof *sieve * length * width)
対 malloc(length * width * sizeof *sieve)
2 番目は length * width
をオーバーフローする可能性があります width
のとき と length
size_t
より小さい型です .
C では、malloc
の戻り値をキャストする必要はありません . malloc
によって返される void へのポインタ 正しい型に自動的に変換されます。ただし、コードを C++ コンパイラでコンパイルする場合は、キャストが必要です。コミュニティの間で推奨される代替手段は、以下を使用することです:
int *sieve = malloc(sizeof *sieve * length);
これにより、 sieve
の型を変更した場合でも、式の右側を変更することを心配する必要がなくなります。 .
人々が指摘したように、キャストは悪いです。特にポインターキャスト。
あなたはする キャストの理由:
- コードの移植性を高める C と C++ の間で、また SO の経験が示すように、非常に多くのプログラマーが、実際には C++ (または C とローカル コンパイラ拡張機能) で書いているのに、C で書いていると主張しています。
- そうしないとエラーを隠すことができます :
type *
と書くタイミングを混乱させる SO の例をすべて書き留めます。 対type **
. #include
に失敗したことに気付かないという考え 適切なヘッダー ファイルが 木には森を欠いている .これは、「コンパイラにプロトタイプが表示されないことについて不平を言うように頼まなかったという事実を心配する必要はありません。厄介な stdlib.h は覚えておくべき本当に重要なことです!」と言っているのと同じです。- 追加の認知クロスチェックを強制します .その変数の生のサイズに対して行っている算術演算のすぐ隣に、(主張されている) 目的の型を配置します。
malloc()
であることを示す SO 調査を行うことができるに違いありません キャストがあると、バグははるかに速くキャッチされます。アサーションと同様に、意図を明らかにするアノテーションはバグを減らします。 - マシンがチェックできるように同じことを繰り返すことは、多くの場合素晴らしい 考え。実際、それがアサーションであり、このキャストの使用はアサーションです。チューリングが何年も前にアイデアを思いついたので、アサーションは今でもコードを正しくするための最も一般的な手法です。