什么是挥发性的extern指针 [英] What is extern volatile pointer

查看:111
本文介绍了什么是挥发性的extern指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是挥发性的extern指针。

What is extern volatile pointer.

extern volatile uint32 *ptr;

在这里,这将是* PTR的行为?
什么,这实际上意味着?

Here, what will be the behavior of *ptr? What does this actually mean?

和,何时应该使用它?

我试图谷歌这件事,但没有得到任何满意的答复,没有关于这个组合很多信息present。

I have tried to google about it, but didn't get any satisfactory answer, there is not much info present about this combination.

推荐答案

两个的extern 的和的挥发性的关键字可以单独考虑。每个这些关键字的作用不与另一种相互作用,并因此它们中的每一个解释可以独立详述如下。

Both extern and volatile keywords can be considered independently. The role of each of these keywords does not interact with the other one, and thus an explanation of each of them can be detailed independently, as below.

的extern 告诉编译器的 PTR 的实际定义在另一个模块(另一个 .C )。基本上,没有太大的变化如何编译器手柄的 PTR 的 - 具有的的extern 的只是告诉它不必保留在内存中的一些空间,为编译器的 PTR 的,因为它是在另一个做过的 .C ,其实际的内存位置将由连接的后面给出。

extern tells the compiler that the actual definition of ptr is in another module (another .c). Basically, there is no much change to how the compiler handles ptr - having extern just tells the compiler that it does not have to reserve some space in memory for ptr as it is done elsewhere in another .c, and its actual memory location will be given by the linker later.

  extern uint32 *ptr;

如果你省略的extern 的编译器不会抱怨。然而,后来的的链接的,当它试图所有的对象模块,以建立最终的可执行程序链接,将抛出一个错误说的 PTR 的被定义了两次(因为它在另一个已经定义 .C )。

If you omit extern the compiler will not complain. However, later, the linker, when it tries to link all object modules in order to build the final executable program, will throw an error saying "ptr is defined twice" (since it is already defined in another .c).

  uint32 *ptr;

挥发性告诉编译器的内存位置的 PTR 的所在,可以改变/由一些外部事件修改,它(编译器)不应该依靠一些效率优化像考虑到的值的 PTR 的C的几个连续的行的范围时将不会改变这样的事件可以是一个异步中断,这种情况发生时,CPU执行上面说的范围,和修改的 PTR 的值。

volatile tells the compiler that the memory location where ptr resides may be altered / modified by some external event, and it (the compiler) should not rely on some efficiency optimizations like considering that the value of ptr will not change during the scope of a few sequential lines of C. Such an event may be an asynchronous interruption, that happens when the CPU executes the above said scope, and modifies the ptr value.

通常情况下(在注释优化的C虚拟装配code),REGx是CPU寄存器,我们不是在变量有兴趣的 ...

Typically (with virtual assembly code of optimized C in comments), REGx are CPU registers, and we are not much interested in the variable y...

  int x = 10;

  int func() {
    int y;              // REG4
    printf("%d\n", x);  // Set REG3 = memory(x) and display x
    x += 2;             // Add 2 to REG3
    y = x * x;          // REG4 = REG3 * REG3
    printf("%d %d\n", x, y); // Do printf(..., REG3, REG4)
    x += 5;             // REG3 = REG3 + 5
                        // memory(x) = REG3 (save register to memory)
    return y;           // return REG4
  }

应该显示 10,12,144 。出于效率的考虑(内存访问更昂贵比寄存器访问)说,编译器店的 X 的的在CPU内部寄存器中的值(REG3),并使用它的 FUNC 的安全,直到它的 X 的新值(这是一个全局变量)存储到的 X 的内存位置结束。 X 的是17日结束。

should display 10, 12, 144. For the sake of efficiency (memory accesses are more costly than register accesses) say the compiler stores the value of x in an internal CPU register (REG3) and uses it in func safely until the end where it stores the new value of x (it's a global var) to x memory location. x is 17 at the end.

但想象中的计划是比这更复杂,有一个时钟中断的减去10的 X 的每一分钟。会发生什么,如果中断...

But imagine the program is more complex than that and has a clock interruption every minute that subtract 10 to x. What happens if an interruption...

  void inter_call_by_timer_every_minute() {
     x -= 10;
  }

...在出现的 FUNC 的说刚过的printf(%d个\\ N,X); 行?的 FUNC 的有 X 的在REG3(10),加2(12),最后加入5(17)和REG3结果存储到的 X 的内存位置(17)。这是错误的,因为中断的影响(-10)一直隐藏在编译器的优化,因为它从REG3内存(x)在年底忽略的减去的通过中断进行存储的值。正确的结果是: X 的最初10,中断(0)后减去10到它的第一个的printf 中的 FUNC ,然后2加,然后5.结果7。

... occurs in func say just after the printf("%d\n", x); line? func has x in REG3 (10), add 2 (12) and finally add 5 (17) and stores the REG3 result to x memory location (17). This is wrong as the interruption effect (-10) has been hidden by the compiler optimization, since it stores the value from REG3 to memory(x) at the end ignoring the subtract done by the interruption. The correct result was: x is initially 10, interrupt subtract 10 to it (0) after the first printf in func, then 2 is added, then 5. Result 7.

添加的挥发性

  volatile int x = 10;

将有编译器避免的 X 的优化中的 FUNC

  int func() {
    int y;              // REG4
    printf("%d\n", x);  // display memory(x)
    x += 2;             // memory(x) += 2
    y = x * x;          // REG4 = memory(x) * memory(x)
    printf("%d %d\n", x, y); // Do printf(..., memory(x), REG4)
    x += 5;             // memory(x) += 5
    return y;           // return REG4
  }

和从内存​​中读取的 X 的价值所有的时间。因此,具有的 inter_call_by_timer_every_minute 的第一个printf后的中断,是的 X 的== 7。

and read the value of x from memory all the time. Result, having an interruption from inter_call_by_timer_every_minute after the first printf, is x == 7.

这篇关于什么是挥发性的extern指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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