0

これは、行を読み取る関数の短いスニペットです。bufsizeそれが比較される可能性はどのようにあり((size_t)-1)/2ますか?

私は変数を例えばと比較することを想像しました。int-それは不可能です。逆にINT_MAXに対しては正しいと思います。では、そのコードは実際にどのように機能し、エラーを発生させないのでしょうか。

int c;
size_t bufsize = 0;
size_t size = 0;

while((c=fgetc(infile)) != EOF) {
    if (size >= bufsize) {
        if (bufsize == 0)
                bufsize = 2;
        else if (bufsize <= ((size_t)-1)/2)
                bufsize = 2*size;
        else {
                free(line);
                exit(3);
        }
        newbuf = realloc(line,bufsize);
        if (!newbuf) {
                free(line);
                abort();
        }
        line = newbuf;
    }
    /* some other operations */
}
4

5 に答える 5

6
(size_t)-1

これは、値を a にキャストしています。Cのキャストです。-1size_t(type)value

は符号なしの型であるためsize_t、これは実際には保持できる最大値であるsize_tため、バッファー サイズを実際に安全に 2 倍にできることを確認するために使用されます (したがって、その後の 2 による除算)。

于 2012-08-31T20:46:12.677 に答える
2

(size_t)-1-1typesize_tにキャストすると、( stdint.hSIZE_MAXで定義されたマクロ)、型が保持できる最大値になります。size_t

したがって、比較では、bufsizeが含まれる最大値の半分以下であるかどうかがチェックされます。size_t

于 2012-08-31T20:50:46.437 に答える
2

コードはビットに関するいくつかの仮定に依存しており、最大の size_t 値を見つけるためによく知られたハックを実行します (size_t がレジスタよりも多くのビットを収容しない場合、多くのマシンでは安全な賭けです)。

最初にレジスタに1ビットを入力し、次にそれをデータ型にキャストしてsize_t、比較が機能するようにします。そのレジスタのビット数がsize_tデータ型よりも大きい限り、未使用のビット (存在する場合)1は切り捨てられ、ビットに収まる最大の符号なし数値が取得されsize_tます。

それが得られた後、2 で割ってその数の半分を取得し、比較を行って、「最大」を超えずにサイズを大きくしても安全かどうsize_tを確認します。しかし、それまでに、データ型を分割し、size_t2 つのデータ型を比較してsize_tいます (タイプ セーフな操作)。

あなたが本当にこのビットウィザードを削除したいのであれば (わかりました、これは私が見たビットウィザードの最悪の例ではありません)。次のスニペットを考慮してください

    else if (bufsize <= ((size_t)-1)/2)
            bufsize = 2*size;

で置き換えることができます

    else if (bufsize <= (MAX_SIZE/2)
            bufsize = 2*size;

キャストせずにタイプセーフになり、読みやすくなります。

于 2012-08-31T20:55:58.837 に答える
0

size_t は値として解釈されず、負の値を size_t 型にキャストするために使用されています。

((size_t)-1)/2

-1 を size_t にキャストしてから 2 で割っています。

于 2012-08-31T20:47:00.540 に答える
0

size_tinは単にキャストとして使用されています((size_t)-1)/2): キャスト-1to size_t.

ここでのトリックsize_tは符号なしであるため、キャストは、または(size_t) -1の最大値に変換されます。これは、ループのコンテキストで役立ちます。ただし、このトリックではなく、直接使用することをお勧めします。size_tSIZE_MAXSIZE_MAX

于 2012-08-31T20:46:26.470 に答える