静态全局变量和静态 volatile 变量有什么区别? [英] What is the difference between a static global and a static volatile variable?

查看:55
本文介绍了静态全局变量和静态 volatile 变量有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在文件范围内使用了一个静态全局变量和一个静态 volatile 变量,

两者都由 ISR 和主循环更新,主循环检查变量的值.

这里在优化过程中,全局变量和 volatile 变量都没有被优化.因此,不是使用 volatile 变量,而是使用全局变量来解决问题.

那么使用全局变量而不是 volatile 好吗?

使用静态 volatile 的任何具体原因?

任何示例程序都是可观的.

提前致谢..

I have used a static global variable and a static volatile variable in file scope,

both are updated by an ISR and a main loop and main loop checks the value of the variable.

here during optimization neither the global variable nor the volatile variable are optimized. So instead of using a volatile variable a global variable solves the problem.

So is it good to use global variable instead of volatile?

Any specific reason to use static volatile??

Any example program would be appreciable.

Thanks in advance..

推荐答案

它们是不同的东西.我不是 volatile 语义方面的专家.但我认为这里描述的内容是有道理的.

They are different things. I'm not an expert in volatile semantics. But i think it makes sense what is described here.

全局只是意味着有问题的标识符在文件范围内声明.有不同的作用域,称为函数(定义 goto 标签的地方)、文件(全局变量所在的地方)、块(普通局部变量所在的地方)和函数原型(函数参数所在的地方).这个概念只是为了构建标识符的可见性而存在.它与优化没有任何关系.

Global just means the identifier in question is declared at file-scope. There are different scopes, called function (where goto-labels are defined in), file (where globals reside), block (where normal local variables reside), and function prototype (where function parameters reside). This concept just exist to structure the visibility of identifiers. It doesn't have anything to do with optimizations.

static 是一个存储持续时间(我们不会在这里看到它)和一种在文件范围内部链接中声明名称的方法.这可以针对仅在一个翻译单元内需要的函数或对象来完成.一个典型的例子可能是一个 help 函数打印出接受的参数,它只能从在同一个 .c 中定义的 main 函数调用文件.

static is a storage duration (we won't look at that here) and a way to give a name declared within file scope internal linkage. This can be done for functions or objects only required within one translation unit. A typical example might be a help function printing out the accepted parameters, and which is only called from the main function defined in the same .c file.

6.2.2/2 在 C99 草案中:

6.2.2/2 in a C99 draft:

如果声明一个文件作用域对象或函数的标识符包含存储类说明静态,标识符有内部联动.

If the declaration of a file scope identifier for an object or a function contains the storage class specifier static, the identifier has internal linkage.

内部链接意味着标识符在当前翻译单元之外不可见(如上面的 help 功能).

Internal linkage means that the identifier is not visible outside the current translation unit (like the help function of above).

Volatile 是另一回事:(6.7.3/6)

Volatile is a different thing: (6.7.3/6)

具有 volatile 限定的对象类型可能会以未知的方式修改实施或有其他未知的副作用.因此任何引用这样一个对象的表达式严格按照到抽象机器的规则,如 5.1.2.3 所述.此外,在每个序列点最后一个值存储在对象中应同意摘要规定的机器,除非由提及的未知因素之前.

An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. Therefore any expression referring to such an object shall be evaluated strictly according to the rules of the abstract machine, as described in 5.1.2.3. Furthermore, at every sequence point the value last stored in the object shall agree with that prescribed by the abstract machine, except as modified by the unknown factors mentioned previously.

标准提供了一个很好的例子,其中 volatile 是多余的 (5.1.2.3/8):

The Standard provides an excellent example for an example where volatile would be redundant (5.1.2.3/8):

一个实现可能定义一个一一对应抽象和实际语义:at每个序列点的值实际对象会同意那些由摘要指定的语义.关键字 volatile那么将是多余的.

An implementation might define a one-to-one correspondence between abstract and actual semantics: at every sequence point, the values of the actual objects would agree with those specified by the abstract semantics. The keyword volatile would then be redundant.

序列点是关于抽象机器的副作用影响完成的点(即不包括外部条件,如存储单元值).例如,在&&|| 的左右之间、; 之后和从函数调用返回的是序列点.

Sequence points are points where the effect of side effects concerning the abstract machine are completed (i.e external conditions like memory cell values are not included). Between the right and the left of && and ||, after ; and returning from a function call are sequence points for example.

抽象语义是编译器可以从只看到特定程序中的代码序列推断出来的.优化的效果在这里无关紧要.实际语义包括写入对象所产生的副作用(例如,更改内存单元).将对象限定为 volatile 意味着人们总是直接从内存中获取对象的值(由未知因素修改").该标准没有在任何地方提及线程,如果您必须依赖更改的顺序或操作的原子性,您应该使用平台相关的方式来确保这一点.

The abstract semantics is what the compiler can deduce from seeing only the sequence of code within a particular program. Effects of optimizations are irrelevant here. actual semantics include the effect of side effects done by writing to objects (for example, changing of memory cells). Qualifying an object as volatile means one always gets the value of an object straight from memory ("as modified by the unknown factors"). The Standard doesn't mention threads anywhere, and if you must rely on the order of changes, or on atomicity of operations, you should use platform dependent ways to ensure that.

为了便于理解概述,英特尔有一篇关于它的精彩文章此处.

For an easy to understand overview, intel has a great article about it here.

继续将您的文件范围(全局)数据声明为 volatile.全局数据本身并不意味着变量的值将等于存储在内存中的值.而 static 只会使您的对象位于当前翻译单元的本地(当前 .c 文件和所有其他由它#include'ed 的文件).

Keep declaring your file-scope (global) data as volatile. Global data in itself does not mean the variables' value will equal to the value stored in memory. And static does only make your objects local to the current translation unit (the current .c files and all other files #include'ed by it).

这篇关于静态全局变量和静态 volatile 变量有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆