2012-04-10 6 views
7

私はちょうどAppleのC/C++コンパイラにフロートをゼロ以外の値(約 "-0.1")に初期化しました。プリミティブ型とは何ですか?デフォルトはCで初期化されていますか?

これは大きな驚きでした。時にはたまにしか起こりませんでした(ただし、同じ関数呼び出し/ argsをあらかじめ実行していた場合は100%反復可能です)。アサーションを使用して追跡するには時間がかかりました。

フロートがゼロで初期化されていると思います。グーグルは、私がC++を考えていたことを示唆しています(もちろん、このようなことについてもっと正確です - c.f.SO:What are primitive types default-initialized to in C++?)。

しかし、おそらくAppleの言い訳は、コンパイラがCモードで動作していたということです。C:どうでしょうか?何が起こるべきか、(もっと重要なのは)典型的なことですか?

は(もちろん私はそれを手動で初期化している必要があります - しかし、私は失敗し、この一つのケースでは、私はそれが、爆破を期待していなかった - 私は通常どおり。!)

(Googleは無用より悪い証明されますこののいずれかの議論のために - 。


、現在の検索は、「C++」せずに「C」と表示することを拒否し、高度なモードで実行している場合でも、私はあまりにも愚かだ決める、とさえ私の入力を無視して保持します)

ここで、実際のです発生したソースの例最初はMAXとABSの定義に問題があると思っていました(多分MAX(ABS、ABS)はいつもあなたが期待していたことをしませんでした)...しかし、アサーションとデバッガを使って掘り下げたところ、初期化 - フロートはごくまれにゼロ以外の値にinit'dなったこと):明示的な初期化子がない場合は

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"); 
+0

「初期化」がどこで行われるかによって、初期化されないことがあります。 – Mat

+0

問題を見つけたソースのコピー/ペーストを追加しました。私はそれがinit'dされていたはずだと思った? – Adam

+1

+1すべての人がその答えを知っているほうが良いという質問をしています。 – borrrden

答えて

17

だけの静的記憶域期間を持つオブジェクトは、0に初期化されます。明示的に初期化されていない(上記の例でhなど)の自動保存期間を有する

#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; 
} 

オブジェクトは不定値を有します。その値を読み取ることは未定義の動作です。

完全性のために、明示的なイニシャライザがない場合は、スレッド記憶期間を持つC11オブジェクトも0に初期化されているためです。

+2

ありがとうございます。ここでは良い答えがたくさんありますが、このようにIMHOを置くと、一目で分かりやすくなります。 – Adam

+0

合意しましたが、私はこの答えの形式が好きです。 –

0

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

+2

他のところで述べたように、ファイルとグローバル変数はデフォルトでゼロに初期化されます。 – Kevin

5

スタティック変数はゼロに初期化されますが、ローカル変数(スタックまたは自動)について話しています - これらのは初期化されていませんが、はそのメモリにありますスタック

9

標準の関連部分は、§6.7.9段落10:

自動記憶域期間を持つオブジェクトが明示的に初期化されていない場合、その値は不定です。静的またはスレッド記憶域期間を持つオブジェクトが明示的に初期化されていない場合は、その後、

:あなたの変数ではなく、スレッドまたは静的記憶域期間を持っていた場合

、その段落の次の部分は有効になります:

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

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

...

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

1

私はこの答えのための私のK & R引き出す必要があった:明示的な初期設定がない場合には

を、外部および静的変数はゼロに初期化されることが保証されています。自動変数およびレジスタ変数は未定義(すなわちガベージ)初期値を有する。

関連する問題