2016-12-08 8 views
1

Cコンパイラは、私が期待していない変数を最適化しているようです。問題のコードは次のとおりです。予期せぬ変数を削除するCオプティマイザ

uint32_t GetSysTick(void); 

uint32_t timeout = GetSysTick() + 9000; //9sec 
while(len && (GetSysTick() < timeout)) 
{ 
    ... some code that will decrement len 
} 

コンパイラは、「タイムアウト」変数を最適化します。通常、whileループはlenがゼロになると終了しますが、プロセスが予想以上に時間がかかると、タイムアウトがタイムアウトを超えたら終了します。もちろん、タイムアウトが最適化されていれば、これは起こりません。タイムアウトを揮発性として定義すると、最適化されずに維持されるはずですが、技術的には揮発性ではないと確信しています。私はここで何が欠けていますか? GetSysTick()の戻り値にvolatileを使用する必要がありますか? (それが正当なものであるかどうかわからない)

完全性のためにここではGetSysTickとsystickの宣言があります。どちらも別のCファイルにあります。 systickは割り込みでミリ秒ごとにインクリメントされます。

static volatile uint32_t systick=0; 

uint32_t GetSysTick(void) 
{ 
    return systick; 
} 
+3

「GetSysTick」はどのように宣言されていますか? [ask]を参照し、[mcve]を提供してください。ビジー待機は良い考えではないことに注意してください。割り込み/セマフォ/タイマなどの使用を改善しました。 – Olaf

+2

あなたはコンパイラがそれをやっていると思いますか?ループ内でタイムアウトを印刷しましたか? –

+0

@AlexK .:あなたはポイントがあります。しかし、変数を出力するためのコードを追加すると、コード生成(Heisenberg-Effect)に影響を与える可能性があります。アセンブリコードを確認するか、デバッガを使用する方がよいでしょう。 – Olaf

答えて

0

私のコンパイラをさらに調査した結果、私は最新バージョンを使用していないことがわかりました。どうやら私は最新のバージョン5.4に更新したgnu arm Cコンパイラバージョン5.2にあったようです。私のタイムアウト変数は最適化されていません。ここのレッスンでは、あなたのツールのアップデートを常にチェックしています。あなたのご意見とご意見をお寄せいただきありがとうございます。 @ JohnBollingerに自分のセットアップでテストする時間をとってくれてありがとう。

関連する問題