如何将 volatile 变量传递给 c 中的函数?

Hal*_*ich 0 c volatile parameter-passing

我想将以下内容传递给 c 中的函数:

#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
Run Code Online (Sandbox Code Playgroud)

以下似乎工作得很好:

void ZeroRegister(unsigned long * _REG) 
{ 
    #define vReg (*((volatile unsigned long *)_REG))
    vReg = 0; 
}
Run Code Online (Sandbox Code Playgroud)

有更好的方法来编码吗?或者我的代码有缺陷?除了它生成的编译器警告之外。

Jon*_*ler 5

您编写函数时需要一个指向易失性内存的指针,这样您就可以避免警告(并且函数中不需要额外的宏):

\n\n
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))\n\nstatic void ZeroRegister(volatile unsigned long *REG)\n{\n    *REG = 0;\n}\n\nint main(void)\n{\n    ZeroRegister(&GPIO_PORTF_DATA_R);\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

在带有 GCC 5.3.0 的 Mac OS X 10.11.4 上,可以使用所示的命令行进行干净的编译(源文件为vui.c):

\n\n
$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \\\n>     -Wold-style-definition -Werror -c vui.c\n$\n
Run Code Online (Sandbox Code Playgroud)\n\n

从函数参数中省略volatile会导致警告(行号和变量名称与上面的代码不匹配;它们是从早期版本的代码生成的):

\n\n
\xe2\x80\xa6\nvui.c: In function \xe2\x80\x98main\xe2\x80\x99:\nvui.c:11:18: error: passing argument 1 of \xe2\x80\x98ZeroRegister\xe2\x80\x99 discards \xe2\x80\x98volatile\xe2\x80\x99 qualifier from pointer target type [-Werror=discarded-qualifiers]\n     ZeroRegister(&GPIO_PORTF_DATA_R);\n                  ^\nvui.c:3:6: note: expected \xe2\x80\x98long unsigned int *\xe2\x80\x99 but argument is of type \xe2\x80\x98volatile long unsigned int *\xe2\x80\x99\n void ZeroRegister(unsigned long * _REG) \n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,上面的编译代码避免使用为实现保留的名称。所有以下划线和大写字母(或另一个下划线)开头的名称都保留用于实现。请参阅 ISO/IEC 9899:2011 \xc2\xa77.1.3 保留标识符:

\n\n
\n
    \n
  • 所有以下划线和大写字母或另一个下划线开头的标识符始终保留以供任何使用。
  • \n
  • 所有以下划线开头的标识符始终保留用作普通名称空间和标记名称空间中文件范围的标识符。
  • \n
\n
\n