2016-04-11 20 views
0

私はC言語で関数に次を渡したい:揮発性変数をcの関数に渡すにはどうすればよいですか?

#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC)) 

次は十分に動作するようです:

void ZeroRegister(unsigned long * _REG) 
{ 
    #define vReg (*((volatile unsigned long *)_REG)) 
    vReg = 0; 
} 

はこれをコーディングするより良い方法はありますか? コードに欠陥がありますか?それが生成するコンパイラの警告以外。あなたが他の変数を渡すよう

+1

なぜ、このために '#define'を使用しますか? '*(volatile unsigned long *)_ REG = 0; 'と書くこともできます。 –

+2

警告はどのように生成されますか? –

+1

アンダースコアと大文字で始まる名前は '実装'用に予約されています。つまり、そのような名前を使用しないでください。 –

答えて

3

あなたはあなただけの引数リストにvolatile修飾子を追加する必要があり、それを同じ方法で渡します

void ZeroRegister(volatile unsigned long * _REG) 
{ 
    *_REG = 0; 
} 

プリプロセッサマクロのトリックを試みる必要はありません。

+0

(そして、Jonathan Lefflerが指摘するように、 '_Xnnnn'名は実装用に予約されています)。 –

4

それは揮発性メモリへのポインタを期待するように、あなたの関数を記述し、その方法は、あなたが警告を回避することができます(と機能で余分なマクロの必要はありません):MacのOS X 10.11で

#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC)) 

static void ZeroRegister(volatile unsigned long *REG) 
{ 
    *REG = 0; 
} 

int main(void) 
{ 
    ZeroRegister(&GPIO_PORTF_DATA_R); 
    return 0; 
} 

示されているコマンドライン(ソースファイルがvui.cである)できれいにコンパイルGCC 5.3.0と0.4:警告につながる関数パラメータから

volatileを省略
$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \ 
>  -Wold-style-definition -Werror -c vui.c 
$ 

(行番号と変数名が一致しません上記のコード。それらは、コードの以前のバージョン)から作製した:コンパイル・コードは、上記実施のために予約名を使用して回避

… 
vui.c: In function ‘main’: 
vui.c:11:18: error: passing argument 1 of ‘ZeroRegister’ discards ‘volatile’ qualifier from pointer target type [-Werror=discarded-qualifiers] 
    ZeroRegister(&GPIO_PORTF_DATA_R); 
       ^
vui.c:3:6: note: expected ‘long unsigned int *’ but argument is of type ‘volatile long unsigned int *’ 
void ZeroRegister(unsigned long * _REG) 

留意されたいです。アンダースコアと大文字(または別のアンダースコア)で始まるすべての名前は、実装用に予約されています。 ISO/IECに9899を参照してください:2011§7.1.3予約識別子:

  • アンダースコアと大文字または別のアンダースコアのいずれかで始まるすべての識別子は常に使用するために予約されています。
  • アンダースコアで始まるすべての識別子は、通常とタグの名前空間の両方でファイルスコープの識別子として使用するために予約されています。
+0

ありがとう、これは素晴らしいソリューションのように見えます。揮発性は、そのアドレスではなく、_REGの内容を参照していますか? static void ZeroRegister(volatile unsigned long * REG) { * REG = 0; } –

+0

はい、「volatile」は、指されているオブジェクトが「volatile」であると言います。ポインタがそれ自体が揮発性であった場合、表記法は 'void ZeroRegister(unsigned long * volatile REG)'になります。これは 'const'に似ています。 –

+0

コメントに 'code'の前後にバックティックを使うことに注意してください。 –

関連する問題