8

AppleのC/C ++コンパイラにfloatをゼロ以外の値(約「-0.1」)に初期化させました。

これは大きな驚きでした-そしてたまにしか起こりませんでした(ただし、同じ関数呼び出し/引数を事前に実行した場合は、100%繰り返します)。(アサーションを使用して)追跡するのに長い時間がかかりました。

フロートはゼロで初期化されていると思いました。グーグルは、私がC ++について考えていたことを示唆しています(もちろん、これについてははるかに正確です-cf SO:C ++でデフォルトで初期化されるプリミティブ型は何ですか?)。

しかし、ここでのAppleの言い訳は、コンパイラがCモードで実行されていたということかもしれません...だから:Cはどうですか?何が起こるべきか、そして(もっと重要なことに)典型的なことは何ですか?

(もちろん、手動で初期化する必要がありました-通常はそうします-しかし、この1つのケースでは失敗しました。ただし、爆発するとは思っていませんでした!)

(グーグルはこれについての議論には役に立たないよりも悪いことを証明しています-彼らの現在の検索は「C ++」なしで「C」を表示することを拒否します。私は愚かすぎると判断し続け、高度なモードで実行しているときでも私の入力さえ無視します)


これが実際に発生したソースの例です。最初は、MAXとABSの定義に問題があるのではないかと思いました(おそらくMAX(ABS、ABS)は必ずしも期待どおりに機能しないのでしょうか?)...しかし、アサーションとデバッガーを調べてみると、最終的には欠落していることがわかりました。初期化-そのfloatは非常に時々ゼロ以外の値に初期化されていました):

float crossedVectorX = ... // generates a float
float crossedVectorY = ... // generates a float

float infitesimal; // no manual init
float smallPositiveFloat = 2.0 / MAX( ABS(crossedVectorX), ABS(crossedVectorY));

// NB: confirmed with debugger + assertions that smallPositiveFloat was always positive

infitesimal += smallPositiveFloat;

NSAssert( infitesimal >= 0.0, @"This is sometimes NOT TRUE" );
4

5 に答える 5

18

0明示的な初期化子がない場合は、静的ストレージ期間を持つオブジェクトのみが初期化されます。

#include <stdio.h>

float f;         // initialized to 0, file scope variables have static storage
static float g;  // initialized to 0

int main(void)
{
    float h;  // not initialized to 0, automatic storage duration
    static float i;  // initialized to 0

    return 0;
}

明示的に初期化されていない自動保存期間(h上記の例のように)を持つオブジェクトの値は不確定です。それらの値を読み取ることは未定義の動作です。

編集: 完全を期すために、スレッドの保存期間を持つC11オブジェクトも0、明示的な初期化子がない場合に初期化されるためです。

于 2012-04-10T13:23:46.953 に答える
9

規格の関連部分は§6.7.9パラグラフ10です:

自動保存期間を持つオブジェクトが明示的に初期化されていない場合、その値は不確定です。

代わりに変数にスレッドまたは静的ストレージ期間がある場合、段落の次の部分が有効になります。

静的またはスレッドの保存期間を持つオブジェクトが明示的に初期化されていない場合、次のようになります。

--ポインタ型の場合、nullポインタに初期化されます。

--算術タイプの場合、(正または符号なし)ゼロに初期化されます。

..。

また、コンパイラの警告(特に初期化されていない変数の警告)をオンにする必要があることにも注意してください。これにより、問題がすぐに特定されるはずです。

于 2012-04-10T13:24:53.497 に答える
5

静的変数はゼロに初期化されますが、ローカル変数(つまり、スタック、または自動)について話していると思います。これらは初期化されませんが、スタック上のそのメモリにある値を取得します。

于 2012-04-10T13:24:28.020 に答える
1

私はこの答えのために私のK&Rを引き出す必要がありました:

明示的な初期化がない場合、外部変数と静的変数はゼロに初期化されることが保証されます。自動変数とレジスタ変数には、未定義の(つまり、ガベージ)初期値があります。

于 2012-04-10T13:27:24.670 に答える
0

Cの標準のどれも、一般的に変数の初期値を定義しているとは思いません。これは、Cの一般的な哲学とアプリケーションドメインと一致します-ある日、コンパイラに変数を初期化させたくない理由があり、それが彼らの責任であることを知っている大人のためのプログラミング独自の変数を初期化します。

于 2012-04-10T13:24:10.627 に答える