Q & A About Volatile & Const (Z)

xiaoxiao2021-03-06  98

Q: a) What does the key b) Can a parameter be Both const and volatile? Give an example c) Can a Pointer Be Volatile? Give An Example A: A, Volatile is the original meaning of "easy change ", That is, the variable will change in a compiler that cannot be predicted. Please do not optimize the compiler (all compilers are optimized to assume the compiler know the variable change law)

Since the speed of the access register is faster, the compiler generally decreases the optimization of the access external RAM. such as:

Static int i = 0; int main (void) {... while (1) {if (i) dosomething ();}}

/ * Interrupt service routine. * / Void ISR_2 (void) {i = 1;}

The original meaning of the program is to call the DOSMETHING function during the main display, but because the compiler determines that there is no modification in the main function, it may only be executed once to the read operation from I to a register, and then each time IF judgment only uses "I copy" in this register, causing DOSMETHING never call. If the variable will be added to Volatile, the compiler guarantees that the read and write operations for this variable will not be optimized (affirmation). This should also be described in this way.

Generally speaking, Volatile is used in several places in the following places: 1. The variables modified for other programs in the interrupt service program need to be added to Volatile; 2. Signs between the shared between the various tasks under multi-task environments should be plus volatile; 3, memory The mapping hardware register is usually also added to the volatile description because each time you read and write it, it may be different;

Alternatively, these cases often consider the integrity of the data (several signs of interrelations read by half are interrupted), and can be implemented in 1, and the task schedule can be disabled in 2. 3. 3 is only a good design of hardware. B, a parameter can both simultaneously combine the volatile and const attributes. c, can. Look below: Do you really understand const and volatile? Const is one of the most commonly used keywords in C , which makes it important to ensure the integrity of the program. It passes such a message between the caller and the caller: I will not change your, rest assured. Volatile is a non-common keyword in C , but each learned people will always know that Volatile indicates that the value of this variable may be changed outside the program. Let's take a look at several procedures (possibly, you can look at the explanation with the following):

// first segment 0000 0001 DWORD __stdcall threadFunc (LPVOID signal) 0002 {0003 int * intSignal = reinterpret_cast (signal); 0004 * intSignal = 2; 0005 while 0006 0 (* intSignal = 1!); 0007 cerr << "ended" << endl; 0008 return 0; 0009} 0010 0011 Void Volatiletriest (DWORD (__stdcall * threadfunc) 0012 {0013 int signal = 1; 0014 Handle H = :: CreateThread (null, 0, Threadfunc, (LPVOID) & signal, 0, null; 0015 Sleep (50); 0016 While (Signal! = 2) 0017 {0018 0; 0019} 0020 CERR << "Hi, stoppppppppp !!!!" << Endl; // if move down? 0021 signal = 1; 0022 :: waitforsingleObject (h, infinite); 0023 :: closehandle (h); 0024} 0025 0026 // second paragraph 0027 class consttest0028 {0029 int mintValue; 0030 int * MintPointer ; 0031 INT & MINTREF; 0032 public: 0033 consttest (): MintPointer (& MintValue) , MIntRef (mIntValue) 0034 {} 0035 int * getIntPointer () const0036 {0037 return mIntPointer; 0038} 0039 int & getIntRef () const0040 {0041 return mIntRef; 0042} 0043 int & getIntValue () const0044 {0045 return mIntValue; 0046} 0047} ; 0048 0049 // Article 3 0050 CHAR FUNC (Const Int I, Const Char * STR) 0051 {0052 Return STR [i]; 0053}

First see the first program, the logic is simple. Create a thread by VolatileTest, execute threadfunc. Because Signal itself is equal to 1, the main thread will wait for its value to become 2, then set it back to 1; this time, threadfunc ends; the main thread ends. However, if you run this program in Release mode, it is generally (all kinds of compilers are optimized.) Dead cycle. why? Because, in VolatileTest, it is placed in a register in a register and then does the value of this register. Like the false code below. MOV AX, Signallabel: IF (AX! = 1) Goto Label Because it is called by the C compiler, it will be modified by other threads. Naturally put it Cache inside the register. Remember, the C compiler is no thread concept! ! ! This time you need to use Volatile. The original meaning of Volatile means that this value may be changed outside the current thread. That is, we have to add the volatile keyword in front of the IntSignal in the Signal and Threadfunc in VolatileTest. At this time, the loop made by the compiler becomes as shown below: Label: MOV AX, Signalif (AX! = 1) Goto Label, the first example first tells a paragraph, let's see the second example. This example is a simple class why MINTPOINTER and MINTREF can be taken out by the const function? The most essential difference between the consttest function and the non-Const function is that the THIS pointer in ConstTest * is constant *, and the THIS pointer in the normal function is constteest * type. That is, when you call the const function, just ensure that its member variables are not changed, there will be no syntax errors. Let's take a look at these three functions. The return value of the first function is a pointer inside (of course, the compiler does not know that it is another member of this class, which does not differ from the compiler). The caller can change the value points to this pointer, but this is not important because const is: this pointer itself will not be changed. The return value of the second function is no problem, but it is a problem with the previous sentence. Because it is clear that a class member will be given this reference. The C compiler is not so smart, it will only have a sentence, this two independent looks no problem, so it passes. The third function can cause a compilation error. This value will be changed because the compiler understands that this value will be changed. To make a more thorough, the return of the first function is to do an implicit conversion from INT * const to INT *. The return of the third function is to convert from const Int to Int &, this is not implicit! ! ! Speaking of int * const, we can say that it and const Int * (that is, int const *). INT * const page; the value indicating that P this pointer can be modified, but this pointer itself cannot be modified. That is, * p = 0; is legal, but p = null is illegal. Const Int * and int Const * are just the opposite.

If you want to declare that a pointer cannot be modified, the value whose points cannot be modified, it is necessary to write into int const * const p; there is a very interesting phenomenon that if you define a Typedef as follows: typedef int * int_pointer ; Then int_pointer const p; and int const * p; is equivalent, not imaginary int * const p; why? I want to think about it (prompt, and GP is related to GP.) When I said, let's see the third program. There is no error in this program, but there is a problem in front and rear consistency. Because in fact, const in front of int is redundant, because the caller is not worried that you will change a pass value parameter. If you do this, please don't care about it in the function, why don't you write a const char *? So long, let's say some written programs related to const and volatile: 1. If you declare a value in the middle of the class, you want to change it in the Const member function, you can add Mutable in front. For example, the square category below, assuming that the calculation area is a fee, you can calculate it when you need it, or save the results. 0000 class Rect0001 {0002 int mBorderSize; 0003 mutable int mArea; 0004 public: 0005 Rect (int borderSize): mBorderSize (borderSize), mArea (-1) 0006 {0007} 0008 void setBorderSize (int borderSize) 0009 {0010 mBorderSize = borderSize 0011 MAREA = -1; 0012} 0013 INT getarea () const0014 {0015 IF (Marea == - 1) 0016 {0017 MAREA = MBORDERSIZE * MBORDERSIZE; 0018} 0019 Return Marea; 0020} 0021}; 2. Const The function does not exist. Because any constant object always needs to have an initial value.

3. Const just indicates that it cannot be changed by explicit statements, is not to say that the value labeled constant will not change. Please refer to the sumUp function of the relevant code. This feature has once led to C (C, which cannot be optimized for some mathematical operations, especially large vector operations. However, with the introduction of Valarray in RESTRICTED and C STL in C99 will be greatly improved.

4. The most important thing is always at the end. When you write multithreaded programs, you must use Volatile (if you haven't used it yet, and there is nothing, because your luck is too good, or because your compiler is too bad. ). If there is such a code: volatile int * signal = ... for (;;) {if (* signal! = 1) SLEEP (100); else {lock (); // do a lot of work with * signal unlock ()}} All the access to * Signal is taken out from memory, then put it back, then remove, then use, ... However, between Lock and UNLOCK, if you can determine Signal The value is not changed by other threads (this is very common), you can complete it in the register, this can be much faster. This situation can be solved like this: volatile int * signal = ... for (;;) {if (* signal! = 1) Sleep (100); else {lock (); int * fastSignal = const_cast Signal); // do a lot of work with * fastsignal unlock ();}} This forced conversion tells the compiler that this value will not be changed.

转载请注明原文地址:https://www.9cbs.com/read-96306.html

New Post(0)