Return C函数中静态volatile变量的值

Return value of static volatile variable in C Function

两种情况:

  1. 一个return静态易失变量值的函数

  2. 直接访问 volatile 变量

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

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

/*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? */

    }
}

在您的代码中,普通编译器几乎无法优化任何内容。在 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 标签暗示的。

现在回答您的问题:

Will an assignment from a function call behave differently than assignment directly from a volatile variable?

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

If so, is there a standard way to access a volatile through a function return?

只有在实现(编译器)可以推断出没有产生副作用的情况下,才能消除函数调用。如果函数访问 volatile,符合标准的编译器不应消除它