C函数中静态volatile变量的返回值

时间:2018-01-18 12:50:26

标签: c embedded volatile irq

两种情况:

  1. 返回静态volatile变量

  2. 的值的函数
  3. 直接访问易变变量

  4. Q1:函数调用的赋值是否与直接从volatile变量赋值的行为不同?

    Q2:如果有,是否有通过函数返回访问volatile的标准方法?

    /*timer.h*/
    extern volatile uint8_t directFlag;
    uint8_t getReturnFlag(void);
    
    
    
    /*timer.c*/
    volatile uint8_t directFlag = 0;   
    static volatile uint8_t returnFlag = 0;
    
    uint8_t getReturnFlag(void)
    {
        return returnFlag;
    }
    
    void timerISR(void)
    {
        directFlag++;
        returnFlag++;
    }
    
    
    
    /*main.c*/
    #include "timer.h"
    
    void main()
    {
        uint8_t a = 0;
        uint8_t b = 0;
    
        while(1)
        {
            a = directFlag;
            b = getReturnFlag(); /* Can this be optimized out? */
    
        }
    }
    

1 个答案:

答案 0 :(得分:2)

在您的代码中,几乎没有任何东西可以通过普通编译器进行优化。在编译main.c时,编译器会看到一个函数调用(getReturnFlag()),它无法知道它包含哪些可能的副作用,即使它知道它,也可以访问volatile变量

出于同样的原因(访问volatile变量是副作用),无法优化对directFlag变量的访问。

ab变量的值从未在main.c中使用,因此两者都可以进行优化。代码等同于:

#include "timer.h"

void main()
{
    while(1)
    {
        (void) directFlag;
        (void) getReturnFlag(); /* Can this be optimized out? */

    }
}

无关:void main()只能在独立环境中接受,我认为这是 embedded 标记所隐含的。

现在提出您的问题:

  

函数调用的赋值是否与直接从volatile变量赋值的行为不同?

访问volatile变量是明显的副作用,因此需要符合要求的实现来评估它。函数调用包含潜在的副作用,因为常见的实现分别编译不同的翻译单元,无法猜测是否会有副作用。但是如果函数的定义在同一个翻译单元中,并且实现可以推断出没有副作用(这里不是这种情况),它可能无法评估它

  

如果是这样,是否有通过函数返回访问volatile的标准方法?

只有实现(编译器)可以推断出没有产生副作用时,才能消除函数调用。如果函数访问volatile,那么符合条件的编译器就不能消除它