Detailed description of volatile keywords in C + + (GO)

Source: Internet
Author: User

1. Why use volatile?

The volatile keyword and the const counterpart in C + +, which are used to modify variables, are often used to establish language-level memory barrier. This is a description of the volatile modifier for BS in "the C + + programming Language":

A volatile specifier is a, hint to a compiler, that an object, its value in ways not specified by the language so That aggressive optimizations must is avoided.

The volatile keyword is a type modifier that declares a type variable that can be changed by factors unknown to the compiler, such as the operating system, hardware, or other threads. When you encounter a variable declared by this keyword, the compiler will no longer optimize the code that accesses the variable, providing stable access to the special address. Declaration-time syntax:int volatile vInt; when the value of a variable declared with a volatile is required, the system always reads the data back from its memory, even if the preceding instruction has just read the data from there. And the read data is saved immediately. For example:

1    volatile int i=ten; 2    int a = i; 3     ... 4    // other code does not explicitly tell the compiler that I have been manipulated 5    int B = i;

Volatile indicates that I is subject to change at any time and must be read from the address of I each time it is used, so the compiler generated assembly code will re-read the data from I's address in B. The optimization approach is that since the compiler found that the code between the I-read data two times does not operate on I, it automatically places the last-read data in B. Instead of re-reading from inside I. Thus, if I is a register variable or represents a port data is prone to error, so volatile can guarantee a stable access to the special address. Note that in VC 6, the General debug mode is not optimized for code, so the role of this keyword can not be seen. This is done by inserting assembly code to test for the effect of a volatile keyword on the final code of the program:

Enter the following code:

 on#include <stdio.h> Geneva     Geneva    voidMain ()Geneva    { to        inti =Ten; .        intA =i; -      ,printf"i =%d", a); the     Ten        //the function of the following assembly statement is to change the value of I in memory One        //but don't let the compiler know A__asm { -mov DWORD ptr [ebp-4], 20h -        } the      -        intb =i; -printf"i =%d", b); -}

Then, running the program in Debug version mode, the output is as follows:

i = 10
i = 32

Then, running the program in Release version mode, the output is as follows:

i = 10
i = 10

The results of the output clearly indicate that the compiler optimized the code in Release mode and did not output the correct I value for the second time. Next, let's add the I statement to the volatile keyword to see what's changed:

 on#include <stdio.h> Geneva     Geneva    voidMain ()Geneva    { to        volatile inti =Ten; .        intA =i; -      ,printf"i =%d", a); the__asm {Tenmov DWORD ptr [ebp-4], 20h One        } A      -        intb =i; -printf"i =%d", b); the

Run the program in Debug and release versions, respectively, with the output being:

i = 10
i = 32

This indicates that the volatile keyword has played its part. In fact, not just the "inline assembly manipulation Stack" is a compilation of unrecognized variable changes, and more likely to be multi-threaded concurrent access to shared variables, a thread changed the value of the variable, how to let the changed value to other threads visible. Generally, volatile is used in several places:
1) Variables modified in the Interrupt service program for other programs need to be volatile;
2) The signs shared between tasks in a multi-tasking environment should be volatile;
3) The hardware registers of the memory map are usually also given a volatile description, because each time it is read and written can be different meanings;

2.volatile pointer

Like the const modifier, const has a constant pointer and pointer constant, and volatile has a corresponding concept:

    • Modifies the object pointed to by the pointer, the data is const or volatile:

1    Const Char* cpch; 2    volatile Char* VPCH;
    • Note: For VC, this feature is implemented after VC 8 is safe.

    • The value of the pointer itself--an integer variable representing the address, is const or volatile:

1    Char Const PCHC; 2    Char volatile PCHV;

Note: (1) You can assign a non-volatile int to a volatile int, but you cannot assign a non-volatile object to a volatile object.

(2) In addition to the basic type, the user-defined type can also be decorated with a volatile type.
(3) A class with a volatile identifier in C + + can access only a subset of its interfaces, a subset controlled by the class's implementation. The user can only use Const_cast to obtain full access to the type interface. In addition, volatile is passed from the class to its members as a const.

3. Volatile under multi-threading

Some variables are declared with the volatile keyword. When two threads are going to use a variable and the value of the variable is changed, it should be declared with a volatile keyword that prevents the optimizer compiler from loading the variable from memory into the CPU register. If a variable is loaded into a register, then two threads are likely to use a variable in memory, one to use a variable in the register, which causes the program to execute incorrectly. Volatile means that the compiler must actually take the variable out of memory each time it is manipulated, rather than using the value in the register already in existence, as follows:

Volatile BOOL bstop = FALSE;
(1) in one thread:
while (!bstop) {...}
bstop = FALSE;
Return
(2) In another thread, terminate the thread loop above:
bstop = TRUE;
while (bstop); Wait for the above thread to terminate, if Bstop does not use the volatile declaration, then this loop will be a dead loop, because Bstop has been read into the register, the value of bstop in the register will never become false, plus volatile, when the program executes, Each time you read the value of bstop from memory, the loop is not dead.
This keyword is used to set the storage location of an object in memory, not in a register. Because a generic object compiler might place its copy in a register to speed up the execution of instructions, such as in the following code:
...
int nmycounter = 0;
for (; nmycounter<100;nmycounter++)
{
...
}
...
In this code, the copy of Nmycounter may be stored in a register (loop, the test and operation of the Nmycounter is always in the value of this register), but there is another piece of code that performs this operation: nmycounter-= 1; The change to Nmycounter is the operation of the in-memory nmycounter, so there is a phenomenon: Nmycounter's change is out of sync.

Detailed description of volatile keywords in C + + (GO)

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.