Talk about the role of volatile 64 recommend a variable that is defined as volatile is that the variable may be unexpectedly altered so that the compiler does not assume the value of the variable. Precisely, the optimizer must carefully reread the value of the variable every time it uses it, instead of using a backup stored in the register. Here are a few examples of volatile variables:
1. Hardware registers for parallel devices (e.g., status registers)
2). Non-automatic variable (non-automatic variables) that is accessed in an interrupt service subroutine
3. Variables shared by several tasks in multi-threaded applications
A person who cannot answer this question will not be hired. I think this is the most basic problem to differentiate between C programmers and embedded system programmers. Embedded system programmers often deal with hardware, interrupts, RTOs, and so on, which require volatile variables. Not knowing volatile content will bring disaster.
Assuming the interviewer has answered the question correctly (well, doubt it will be), I'm going to delve a little deeper and see if this guy is straight and understands volatile's full importance.
1. Can a parameter be either a const or a volatile? explain why.
2). Can a pointer be a volatile? explain why.
3). What's wrong with the following function:
int square (volatile int *ptr)
{
return *ptr * *PTR;
}
Here is the answer:
1). 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). Yes. Although this is not very common. An example is when a medium service subroutine fixes the pointer to a buffer.
3. There's a prank on this piece of code. 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:
int square (volatile int *ptr)
{
int a,b;
A = *ptr;
b = *ptr;
return a * b;
}
Because the value of the *ptr can be unexpectedly changed, A and B may be different. As a result, this code may not return the square value you expected. The correct code is as follows:
Long Square (volatile int *ptr)
{
int A;
A = *ptr;
Return a * A;
}
Speaking of my understanding: (Welcome Tai ... ~ ~.) )
The key is two places:
1. Compiler optimization (please help me to see the following understanding)
In this thread, when reading a variable, in order to improve access speed, compiler optimization sometimes read the variable to a register, and then take the variable value, directly from the register value;
When the value of the variable changes in the Chengri, the new value of the variable is also added to the register to keep the same
When a variable changes the value due to another thread, the value of the register does not change, causing the application to read the value and the actual variable value is inconsistent
When the register changes value because of another thread, the value of the original variable does not change, causing the application to read the value and the actual variable value is inconsistent
Give a less-than-accurate example:
When it comes to payroll, every time the accountant calls the employee to register their bank card number; In order to save trouble, the accountant did not register immediately, used the bank card number which was previously registered; just one employee's bank card has been lost and the bank card number has been reported, causing the employee to receive no pay
Employee--Original variable address
Bank card number--the original variable in the Register backup
2. Under what circumstances will it appear (as stated on the 1 floor)
1. Hardware registers for parallel devices (e.g., status registers)
2). Non-automatic variable (non-automatic variables) that is accessed in an interrupt service subroutine
3. Variables shared by several tasks in multi-threaded applications
Add: Volatile should be interpreted as "direct access to the original memory address" more appropriate, "variable" This explanation is a bit misleading;
"Variable" is due to external factors, such as multithreading, interruptions, and not because the volatile modified by the variable is "easy to change", if there is no external cause, that is, the use of volatile definition, it will not change;
And with the definition of volatile, in fact, this variable will not change due to external factors, you can rest assured that the use of; let's see if the previous explanation (variable) is misleading.
------------Concise examples are as follows:------------------
The volatile keyword is a type modifier that declares a type variable that can be changed by factors unknown to some compilers, such as operating system, hardware, or other threads. When you encounter a variable that is declared by this keyword, the compiler will no longer optimize the code that accesses the variable, thus providing a stable access to a particular address.
Examples of using this keyword are as follows:
int volatile nvint;
>>>> when asked to use the value of a variable declared by volatile, the system always reads the data back from its memory, even if the previous instruction has just read the data from that point. And the data being read is saved immediately.
For example:
volatile int i=10;
int a = i;
...
Other code that does not explicitly tell the compiler that the I has been manipulated
int b = i;
>>>>volatile points out that I is subject to change at any time and must be read from the address of I whenever it is used, so that the compiler-generated assembly code will again read the data from I to the address in B. The optimization approach is that because the compiler finds that the code in the code between the two times I read data does not operate on I, it automatically places the last read data in B. Rather than re reading from I. Thus, if I is a register variable or a port data is prone to error, so volatile can guarantee a stable access to special addresses.
>>>> Note that in VC6, the General debug mode is not optimized for code, so the role of this keyword cannot be seen. The following inserts the assembly code to test for the volatile keyword, the effect on the program final code:
>>>> first, build a Win32 console project with ClassWizard, insert a voltest.cpp file, and enter the following code:
>>
#i nclude <stdio.h>
void Main ()
{
int i=10;
int a = i;
printf ("i=%d", a);
The purpose of the following assembly statement is to change the value of I in memory, but not to let the compiler know
__asm {
mov dword ptr [ebp-4], 20h
}
int b = i;
printf ("i=%d", b);
}
Then, run the program in debug version mode, and the output is as follows:
i = 10
i = 32
Then, run the program in Release version mode, and the output is as follows:
i = 10
i = 10
The results of the output show that, in release mode, the compiler optimizes the code and does not output the correct I value for the second time. Below, we add the declaration of I to the volatile keyword to see what changes:
#i nclude <stdio.h>
void Main ()
{
volatile int i=10;
int a = i;
printf ("i=%d", a);
__asm {
mov dword ptr [ebp-4], 20h
}
int b = i;
printf ("i=%d", b);
}
Run the program separately in the debug and release versions, and the output is:
i = 10
i = 32
This means that the keyword has played its part.
------------------------------------
Volatile the corresponding variable may change in the event that your program itself does not know
For example, multithreading programs, common access to the memory, multiple programs can manipulate this variable
Your own program, is not able to determine the appropriate variable will be changed
For example, he corresponds to a certain state of an external device, and when an external device occurs, the system changes the value of the variable through the driver and interrupt event, and your program does not know.
For the volatile type of variable, each time the system uses it is directly extracted from the corresponding memory, and will not take advantage of the original cache value, in order to adapt to its unknown when the changes will occur, the system will not do to optimize the processing of such variables- Obviously also because its value can change at any time.
--------------------------------------------------------------------------------
A typical example
for (int i=0; i<100000; i++);
This statement is used to test the speed of the empty loop.
But the compiler is definitely going to tune it out and not execute it at all.
If you write
for (volatile int i=0; i<100000; i++);
It's going to execute.
Volatile was meant to be "variable."
Because the speed of access registers is faster than RAM, the compiler generally makes optimizations to reduce access to external RAM. Like what:
static int i=0;
int main (void)
{
...
while (1)
{
if (i) dosomething ();
}
}
/* Interrupt Service routine. */
void isr_2 (void)
{
I=1;
}
The intention of the program is to call the DoSomething function in main when the isr_2 interrupt is generated, but because the compiler determines that I has not been modified in the main function,
It is possible to perform only one read operation from I to a register, and then each if judgment only uses the "I copy" of the Register, causing DoSomething to never be
Call. If you add volatile to the variable, the compiler guarantees that the read-write operation on this variable will not be optimized (definitely executed). I should also say so in this example.
Generally speaking, volatile is used in several places as follows:
1, the interruption of the service program for other procedures to detect the variables need to add volatile;
2. The volatile should be added to the signs shared between tasks in a multitasking environment;
3, memory mapping hardware registers are usually added volatile description, because each of its reading and writing may be different meaning;
In addition, these situations often have to take into account the integrity of the data (a number of interrelated flags read half of the interrupted rewrite), in 1 can be broken to real
Now, 2 can prohibit task scheduling, 3 only rely on the good hardware design. Http://blog.21ic.com/user1/2949/archives/2007/35599.html