2017-10-10 20 views
1

私は、次のCコードがあるとします。今C:「ゲッター」機能や、中断して静的揮発性を利用し

/* clock.c */ 

#include "clock.h" 

static volatile uint32_t clock_ticks; 

uint32_t get_clock_ticks(void) 
{ 
    return clock_ticks; 
} 

void clock_tick(void) 
{ 
    clock_ticks++; 
} 

私はclock_tickを呼び出していますが:からget_clock_ticks()の呼び出し中に、中断中(すなわちclock_ticks変数をインクリメント) main()機能(すなわち、中断の外側)。

私の理解では、clock_ticksは、特に指定のない限り、コンパイラはそのアクセスを最適化し、main()は(それが実際に中断から変更しながら)値が変更されていないと思わせることができvolatileとして宣言されなければならないということです。

直接(すなわち:staticとしてそれを宣言していない)main()を形成するがget_clock_ticks(void)機能を使用して、代わりの変数にアクセスすると、実際にそれがvolatileとして宣言されていない場合でも、メモリから変数をロードするようにコンパイラに強制することができているのだろうか。

誰かがこれが起こってできた私に言ったように私はこれを疑問に思います。本当ですか?どのような条件の下で?とにかく私が "ゲッター"機能を使用すれば、私はいつもvolatileを使うべきですか?

+0

あなたの場合の「揮発性」は必須です。それは、変数が割り込みからアクセスされるときに差をつけています。このようにして、コンパイラは、変数にアクセスして変更することが知られている変数を知っていることを知ります。さもなければあなたの "ゲッター"は変数の一定の初期値を返すでしょう。 –

+0

https://stackoverflow.com/questions/5822386/the-volatile-keyword-in-c-language –

+0

getter関数はインライン展開される可能性があります。キャッシュコヒーレンシの問題があり、それが非決定論的な振る舞いをする可能性があります。 @EugeneSh。 – jxh

答えて

2

getter関数は、volatileを使用しての上に、ここでどのような方法では役立ちません。

  • コンパイラでは、2行上の値を取り出してから変更していないものとします。
  • それが良い最適化コンパイラなら、私はそれは、関数呼び出しは、単に関数呼び出しを最適化する何の副作用を持っていない見ることを期待します。

get_clock_ticks()は(すなわち、別のモジュールで)externalだろう場合は、問題は異なっている(多分それはあなたが覚えているものです)。

通常のプログラムフロー(ISRなど)の範囲外で値を変更できるものはです。volatileとする必要があります。

+0

答えをありがとう。誰かが何かをここに追加したい場合に備えて、明日まで受け入れます。 ^^ – Peque

+0

表示されているコードは 'clock.c'ファイルからのもので、' clock.h'というヘッダが含まれています。クロック機能を使用するコード(例えば、 'main()'を含むファイル)はヘッダのみを含み、どちらの関数をインライン化する機会もありません。もちろん、OPが 'clock.c'ファイルをインクルードすることを止めるものは何もありませんが、それは期待されるものではありません。 (このコードでは割り込みの設定方法なども示されていません) –

+0

@JonathanLeffler "clock.c"のすべてを見たとしますか?私は必ずしもそうではありません。 'get_clock_ticks()'が "clock.c"の外側または内側から呼び出されたときに最適化のオプションに違いがあります( "動作しない"ために悪化します)。 – tofro

1

は、現在のコード宣言get_clock_ticks、別のモジュールとしてそれを使用してコードをコンパイルした場合でも、多分1日あなたはリンク時またはクロスモジュールの最適化を使用することを忘れないでください。ゲッター関数を使用していても、 "volatile"のままにしておけば、この場合はコード生成に問題はなく、正しいコードになります。あなたが言及していない

ことの一つは、プロセッサのビットサイズです。 1回の操作で32ビットの値を読み取ることができない場合、読み取りがアトミックではないため、get_clock_ticks()が失敗することがあります。

+0

ありがとうございます。ええ、それは32ビットARMです。 – Peque