4

少し前に、間違った数値データがログ ファイルに書き込まれる原因となるバグ a を探していました。問題は、次と同等のコードであることが判明しました。

int main(void) {
    struct {
        double a;
        int b;
    } s = { 1, 2 };

    printf("%lf\n", s.a);
    printf("%lf\n", s.b);
}

出力していた

1.000000
1.000000

どうやらprintf、スタックではなく、浮動小数点レジスタの 2 番目の値を期待していたようです。将来このような間違いが起こらないようにするには、すべての printf パラメータをキャストして、実際に期待される型であることを確認する必要がありますか?

4

5 に答える 5

5

C99規格による。出力する実データの書式指定子とデータ型の不一致Undefined behavior

bこれが int なので、"%d"2 番目のprintf()関数で指定した場合。それ以外の場合は正しい値を出力しますBehavior is Undefined

c99から

7.19.6 9 If a conversion specification is invalid, the behavior is undefined.242) If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined

于 2013-08-30T10:46:53.817 に答える
2

すべての printf パラメータをキャストして、実際に期待されるタイプであることを確認する必要がありますか?

タイプが予想と異なる場合は、はいコンパイラの警告を有効にすると、これが通知されます。

printf のテンプレート指定子が、値を表示するスタイルを示しているという信念に基づいて行動していると思われます。これは部分的に真実であり、(キャストを介して) 主要な目的で機能させることができますが、主要な目的は、考慮されている値の種類を printf に示すことです。

したがって、整数型がある場合は、を使用できますが、を使用することはでき%dません%f。これ%fは嘘であり、コンピューターに嘘をつくのは難しいビジネスだからです。の目的が%f小数点以下の桁数で値を出力することである場合は、キャストする必要があります。これにより、整数値が浮動小数点数に適切に変換されます。%d.000000(とにかく整数には小数がないので、単に使用することもできます)。

それ以外の場合は、型に適した指定子を使用する必要があります。

于 2013-08-30T10:54:28.300 に答える
0

正直なところ、データ型を struct { double a; から変更すると、int b; } s = { 1, 2 }; 構造体へ { double d_a; int n_b; } s = { 1, 2 };

ハンガリー語表記を使用しなくても、変数にタグを使用してタイプ情報を提供します。次に、printf("%lf\n", s.n_b); と入力すると、ここでトラップを簡単に見つけることができます。

C の型キャストには、さまざまなプラットフォームで悪影響があります。彼らはトリッキーでずさんです。問題を解決する他の方法がある場合は、型キャストを使用しないでください。

于 2013-08-30T13:52:19.267 に答える