-1

以下に説明する動作は予測可能ですか?

数値を 2147483648 の制限になるように編集しました。まだ機能しているようです。それは予測可能ですか?

a.out 実行

e1r4p22% ./a.out
-2147483648
4

main.c

#include <stdio.h>
int main()
{
    int i = 2147483648;
    i = -i;
    printf("%d\n", i);
    printf("%lu\n", sizeof(int));
    return 0;
}
4

2 に答える 2

1

質問を変更したため、以前の回答が無効になります。

一般に、プログラムの動作は予測できません。

C 標準では、 が~(16 ビット)intの範囲の値を表現できることのみが保証されています。このようなシステムでは、定数のタイプはorです。-32767+327672147483648longlong long

int32 ビットで、パディング ビットがなく、2 の補数で2147483648あっても、 の範囲外でありint、タイプがlongまたはである可能性がありますlong long

これ:

int i = 2147483648;

またはの値を暗黙的に に変換します。結果は実装定義です -- または、実装定義のシグナルを発生させることができます。longlong longint

多くのシステムでは、実装定義の結果は になります-2147483648。もしそうなら、これは:

i = -i;

はその値を否定しようとし、 の範囲外の結果をもたらしますint。変換とは異なり、単項などのオーバーフロー算術演算子は-、符号付き型に対して未定義の動作をします。

プログラムがシステム上での動作と同じように動作する可能性は非常に高いですが、C 標準に関する限り予測できません。コンパイラは、プログラムの動作が適切に定義されていると自由に想定し、その想定に基づいてコードを生成するため、予期しない方法で動作する可能性があります。

また:

printf("%lu\n", sizeof(int));

(演算子の結果) がシステム上にある場合、 これは正しく機能します。そうでない場合も、未定義の動作になります。の正しい形式は次のとおりです。size_tsizeofunsigned longsize_t"%zu"

printf("%zu\n", sizeof(int));

これは C99 で導入されたため、一部の実装 (特に Microsoft の実装) ではサポートされていない可能性があります。キャストを使用して、引数を適切な型に変換することもできます。

printf("%lu\n", (unsigned long)sizeof(int));

このコードが達成しようとしているものが何であれ、それを行うためのより明確な方法がほぼ確実にあります。の値で整数を操作できるようにしたい場合2147483648long longまたはint64_tは十分な大きさであることが保証されています。

于 2013-07-19T21:58:46.267 に答える
0

limits.hint の制限は、およびによると 2 147 483 647sizeof(int) = 4です。はい、2 147 483 148 < 2 147 483 647 なので、予測可能です。

于 2013-07-19T21:34:52.233 に答える