C + + Keywords: volatile

Source: Internet
Author: User

Volatile is the meaning of "variable" and "unstable". Volatile is a keyword in C + + that resolves an issue that is prone to read errors in a "shared" environment.

In a single-tasking environment, within a function body , if the statement between the values of the two read variables does not modify the value of the variable, the compiler will try to optimize the executable code. Since the access register is faster than RAM (reading the value of a variable from RAM to the register), the value of the variable is read from the register and not accessed by the RAM as long as the value of the variable is not changed.

This is an optimization process in a single-tasking environment, but it is the cause of the problem in a multi-tasking environment.

In a multitasking environment, although there is no modification of the value of a variable between two read variables within a function body, the variable may still be modified by other programs (such as interrupt programs, additional threads, and so on). If the value of a variable is read from a register rather than from RAM, there is a problem that the modified Biarron cannot respond in a timely manner. The following procedure simulates this phenomenon:

#include <iostream>usingnamespacestd;int main(int argc,char* argv[]){    int i=10;    int a=i;    cout<<a<<endl;    _asm{        mov dword ptr [ebp-4],80    }    int b=i;    cout<<b<<endl;    return0;}

The program generates release versions in the VS2012 environment (it must be optimized for extreme optimizations, and the optimization speed is maximized in the VS compilation Environment/o2), and the output is:
10
10

By the way, EBP is an extended base point pointer Register (extended base pointer) that holds a pointer to the bottom of the top stack frame of the system stack.

Actually already through inline assembly, modified values, why print out or 10?

But if:

the int i=10; This is not the case with pre-and volatile.

Trace assembly code can be found that any variable that is declared volatile, each time the value obtained is directly read from memory.

The following experiments are carried out in the VS2012 release environment.

No volatile
int i=Ten;int A=i;TMP (a);xxD71273PushDWORD ptr ds:[0D73024H]xxD71279movEcx,dword ptr ds:[0D7303CH]xxd7127fPush        0AhxxD71281PagerDWORD ptr ds:[0D7302CH]xxD71287movEcx,eaxxxD71289PagerDWORD ptr ds:[0D73028H] _asm{movDWORD ptr [ebp-4], thexxd7128fmovDWORD ptr [ebp-4], -h} int B=i;TMP (b);xxD71296PushDWORD ptr ds:[0D73024H]xxd7129cmovEcx,dword ptr ds:[0D7303CH]xxD712a2Push        0AhxxD712a4PagerDWORD ptr ds:[0D7302CH]xxD712aamovEcx,eaxxxD712acPagerDWORD ptr ds:[0D73028H]
Added volatile.
TMP (a);01201274  PushDWORD ptr ds:[1203024h] volatile int i=Ten;0120127AmovDWORD ptr [i],0Ah int A=i;01201281  movEax,dword ptr [i] tmp (a);01201284  movEcx,dword ptr ds:[120303CH]0120128APushfa[0120128BPagerDWORD ptr ds:[120302CH]01201291  movEcx,eax01201293  PagerDWORD ptr ds:[1203028H] _asm{movDWORD ptr [ebp-4], the01201299  movDWORD ptr [i], -h} int B=i;012012A0movEax,dword ptr [i] tmp (b);012012A3PushDWORD ptr ds:[1203024H012012A9movEcx,dword ptr ds:[120303CH]012012AfPushEAX tmp (b);012012B0PagerDWORD ptr ds:[120302CH]012012B6movEcx,eax012012B8PagerDWORD ptr ds:[1203028H

Due to the compiler's extreme optimizations, it is obvious that, without the addition of volatile, even the compiler is directly using the operand 0Ah for the operation.

In the case of volatile, each time it is read from PTR [i].

And in the case of extreme speed optimization,

void tmp(int t) {    cout<<t<<endl;}

also automatic inline processing.

But here also throws a question, why is [ebp-4] modified is the value of I, even more strange, if I write code like this, it will change the value of which variable:

#include <iostream>using namespace STD;voidtmpintT) {cout<<t<<endl;}intMainintargcChar* argv[]) {volatile intIc= A;volatile intI=Ten;intA=i;volatile intib= One;    TMP (a);    TMP (IB); TMP (IC);//must be used, if not used, the compiler optimizes to use the same piece of memory address_asm{mov dword ptr [ebp-4], the}intB=i; TMP (b);return 0;}

Why is the allocation always [ebp-4] A value copied to a? Test, if the IC is assigned to a, then [ebp-4] will be stored in the value of the IC

Read the above procedure and pay attention to the following points:
(1) The above code must be examined in release mode, since only the release mode (which strictly requires maximum speed optimization/o2) will be optimized for program code, which is prone to problems in variable sharing environments.

(2) Variables that need to be shared by multiple tasks, such as variables that may be accessed by the Interrupt service program, variables accessed by other threads, should be declared as volatile variables. And in order to improve the efficiency of implementation, to reduce the use of volatile unnecessary.

(3) Because optimizations may remove some "useless" code completely, you can declare variables in them as volatile if you do want to keep this part of the code in the executable file:

int main(int argc,char* argv[]){    int s,i,j;    for(i=0;i<100;++i)        for(j=0;j<100;++j)            s=5;    return0;}

When generating the release version of the program, because the loop body gives the value of S at each time (simplified to 1 times), or not used (1 times none), but if the program ape is the hope that the loop delay time, written as volatile can be.

Appendix: Questions

1) can a parameter be either const or volatile? explain why

Yes. An example is a read-only status register. It is volatile because it can be changed unexpectedly. It is const because the program should not attempt to modify it.

2) Can a pointer be volatile? explain why

Yes. Although this is not very common. An example is when an interrupt service subroutine fixes a pointer to a buffer.

3) What is wrong with the following function:

intint*ptr) {     return*ptr*ptr

The purpose of this code is to return the pointer *ptr to the square of the value, but since *ptr points to a volatile parameter, the compiler will produce code similar to the following:

intint*ptr) {     int a,b;     *ptr;     *ptr;     return

Because the values of the *ptr can be unexpectedly changed, A and B may be different. As a result, this code may return
The square value you expect! The correct code is as follows:

long square(volatile int *ptr) {     a;     a = *ptr;     returnaa

C + + Keywords: volatile

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.