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

标签 c parameter-passing volatile

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

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

以下似乎工作得很好:

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

有没有更好的编码方式? 还是我的代码有缺陷?除了它生成的编译器警告。

最佳答案

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

#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;
}

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

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

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

…
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 保留标识符:

  • All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.
  • All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.

关于c - 如何将 volatile 变量传递给 c 中的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36540757/

相关文章:

c - 数组不在 C 中存储/显示整个字符串

c++ - C++重载通用方法,按引用和按值

listview - 如何通过 Flutter 中的 RaisedButton 传递/绑定(bind)值?

java - 了解 Java volatile 可见性

c++ - 从语法的角度来看, "volatile"关键字在 C++ 函数中有多少次用法?

c - 用字符串做数学?

python - 如何将 PyFrameObject 转换为 PyObject

c - 如何动态改变数据类型?

ios - 如何将特定元素从数组传递到另一个 View 或函数? swift

c - 声明为常量和 volatile 的指针