宣言の配列の前に"通常の"変数。
-
22-09-2019 - |
質問
現在の申msp430MCUと、走った。されることを宣言する配列をピンタバコ会社の本社対象範囲の後に宣言"通常の"変数 時には 原因はどのように定義されません。このように:
foo(int a, int *b);
int main(void)
{
int x = 2;
int arr[5];
foo(x, arr);
return 0;
}
fooが渡されたポインタとしての変数 時には ない点に arr 配列に格納します。確認していますこの単一ステッピングを通じて、プログラムを見ることの価値に着配列としてポインタ変数の範囲は同一の値としてはインフレーションのポインタ変数のfooます。となっreproduceableしてだけでこれだけ挙動のだ。
これは観測可能なものと単線のfoo機能が実行され、渡されたポインタのパラメータ(b)は、単になることを指摘し、アドレスに着です。
変化の例のように問題の解決のため、このように:
foo(int a, int *b);
int main(void)
{
int arr[5];
int x = 2;
foo(x, arr);
return 0;
}
なんて入力またはヒントにした体験的に振る舞えるのでしょうか?または類似体験?のMSP430プログラミングガイドを指定するコードに準拠しANSI C89。な破壊も修復もおもしろくないという配列を宣言される前に非配列変数には?
入力ことによりお願い申し上げます。
更新
@Adam Shiemkeとtomlogic:
私は何C89を指定してこれまでとは異なる初期化値を宣言も行いました。ませ書きのようなもの:
int bar(void)
{
int x = 2;
int y;
foo(x);
}
る場合は、どうでしょう:
int bar(int z)
{
int x = z;
int y;
foo(x);
}
はとです。こさないようにするものとしますの違法C89:
int bar(void)
{
int x = baz();
int y;
foo(x);
}
よろしくお願いします。
更新2 問題を解決しました。基本的にまたが無効に割り込みを行う前の呼び出し機能(foo)後の宣言の変数.まるで再生することができる問題の簡単な例とソリューション問題解決をきめの追加_NOP()書を無効に割り込みます。
場アクセラレータ-プログラムも興味があっきの例では再生の問題の修正?
全体的に入力します。
解決
あなたはそれが生成されるアセンブリコードに基づいて、コンパイラのバグがあるかどうかを判断することができるはずです。あなたは変数宣言の順序を変更したときにアセンブリ違うのですか?デバッガがあなたを許可する場合は、アセンブリを介してシングルステップを試してみます。
あなたはコンパイラのバグを発見した場合は、、また、あなたの最適化を確認してください。私は、オプティマイザによって導入され、このようなバグを見てきています。
他のヒント
コンパイラのバグのように見えます。
それ あなたが最初の例(問題1)を使用し、foo(x, &arr[0]);
としてあなたの関数呼び出しを記述する場合は、は、あなたが同じ結果を見ていますか?あなたがint arr[5] = {0};
のような配列を初期化する場合は?これらは何も変更する必要がありますが、彼らがしなければ、それはコンパイラのバグをほのめかすでしょう。
あなたの更新の質問には:
基本的に、我々はどこ機能(
foo
)を呼び出す前に、変数の宣言の後に割り込みを無効にします。私たちはどこ単純な例では、問題を再現することができ、そしてこの溶液を無効に割り込みコールの後_NOP()
文を追加するようです。
それがために命令を引き起こしている可能性があります固有/機能を無効に割り込み/マクロ(またはただし、割り込みが無効になっている)かのように聞こえる「スキップ」または何か。私は、それが正しく動作/コーディングされているかどうかを調べると思います。
どちらの例も、私にはC89を準拠するように見えます。 foo
が配列の境界を越えてアクセスしていないと仮定しての行動で観察可能な違いがあってはならない。
C89の場合、変数は任意の割り当て前のスコープの開始時リスト内で宣言する必要があります。 C99は、あなたが割り当てに宣言を混在させることができます。だから、ます:
{
int x;
int arr[5];
x=5;
...
法的C89のスタイルです。私はそれはC99をサポートしていない場合は、あなたのコンパイラがその上で何らかのエラーをスローしませんでした驚いています。
は、実際のコードははるかに複雑であると仮定すると、私は彼らが推測されている心に留めておく、チェックするいくつかのことを相続ます:
あなたは機会に、スタックがオーバーフローしていませんか?もしそうなら、これはコンパイラ/のuCによって「スタック防衛」のいくつかのアーティファクトだろうか? &FOOの不正な値は、予測可能なメモリの範囲内に落ちるのか?もしそうなら、その範囲はいかなる意味を持っていない(など、スタック内の)?
mcu430はRAMとROMのアドレス指定のために異なる範囲を持っていますか?つまり、プログラムのアドレス空間は24bitながら、ラム16ビットのアドレス空間がありますか? PICのは、例えば、このようなアーキテクチャを有します。そのその範囲を超える場合は、ARRが最初に16ビットのアドレス空間が、レンガの中に配分されたとき、ARRは、ROM(24ビット)として割り当てられてきていると関数は、ポインタが(16ビット)のラムを期待したコードが動作することを可能になるようであれば。
たぶん、あなたはあなたのスタックを破壊し、不正なメモリ書き込み中に、あなたのプログラム内のいくつかの場所で持っています。
あなたが解体?
を見ていました