首页 文章

在c中转换volatile变量

提问于
浏览
3

我想我有一个棘手的问题,但我相信你能帮助我 . 假设我有这样的函数:

char my_function (int example);

我在多种情况下使用此函数,有时它接收的参数是volatile变量,有时是非易失性变量 . 当我编译可以通过使用强制转换轻松删除的代码时,这会引起一些警告,但我想了解哪个是更安全的场景以及为什么 .

场景1:

原型: char my_function (int example);

int a;
volatile int b;

my_function (a);  // Everything is fine.
my_function ((int)b);  // Avoided the warning, by casting the variable and            saying it's no longer volatile.

场景2:

原型: char my_function (volatile int example);

int a;
volatile int b;

my_function(b);  // Everything is fine.
my_function((volatile int)a); // Avoided the warning, by casting 'a' saying that now it's volatile.

我理解volatile修饰符是如何工作的,我主要使用它,因为我编写了微控制器,我需要确保我的一些变量在硬件修改时永远不会被优化掉 . 我对于生成volatile修饰符有点困惑,这就是为什么我想要了解除了删除警告之外哪个更安全的情况 .

2 回答

  • 1

    这真的取决于 my_function does 与其论点 .

    请记住, volatile 会阻止某些优化 - 主要是它会强制每次引用变量时重新读取它 . 因此这段代码

    volatile int a;
    int b;
    // ...
    b = a + 1;
    b = a + 2;
    

    将为每个语句读取 a ,并且由于 a 可能已更改它们之间的值,因此请给出正确的结果 .

    volatile 作为参数传递给函数时,只能获得一个变量的 read . 然后可以在函数内多次使用它(实际上失去了 volatile 性质) .

    请记住,C是按值传递 . 当您调用该函数时

    my_function((int)b); // b is declared volatile
    

    编译器生成代码以在调用代码中读取 b 一次,并将其读取的值推送到堆栈(通常),然后调用 my_function . 然后在 my_function 中将此副本引用为 example ,无论您多久引用 example ,您将始终获得相同的值(即使原始的 b 变量已经多次更改) .

    这可能正是您想要的 - 获取变量的快照并对其值进行多次计算 .

    如果它不是您想要的,您需要考虑使用相应的 volatile 资格传递 pointer .

    char my_function( volatile int *example);
    

    并称之为:

    my_function(&a);
    my_function(&b);
    

    然后在 my_function 内引用 *example .

  • 3

    演员实际上没有做任何事情 . 在调用my_function(b)中;代码读取volatile int b . 在阅读期间,这就是“易变”的重要因素 . 读取的结果已经是int而不是volatile int . 没有volatile int值 . 即使存在volatile int值,将其传递给my_function也会将其转换为plain int,就像强制转换一样 .

    可能是编译器假定将volatile变量传递给函数是危险的值得警告,并且通过向int添加强制转换,表明您知道自己在做什么 .

相关问题