Mutable Keyword Mutable is a non-commonly used keyword in C , which can only be used for non-static and very amount of data members we know that the status of an object is determined by the non-statically data member of the object, so with data Members change, the status of the object will also change! If a member function of a class is declared as a const type, it means that the function does not change the status of the object, that is, the function does not modify the class's non-static data member. But sometimes you need to assign a value of the class's data in this class function. This time you need to use the Mutable keyword, for example: Class demo {public: demo () {} ~ demo () {} public: Bool getFlag () const {m_naccess ; return m_bflag;} private: int m_naccess; Bool M_bflag;}; int main () {return 0;} Compile The above code will appear Error C2166: L-Value Specifies Const Object error Description In Const Type The function is changed in the function. This time you need to use Mutable to modify the non-static data member m_naccess that is changed in the Const member function. The code is as follows: Class demo {public: demo () {} ~ demo ) {} public: bool getflag () const {m_naccess ; return m_bflag;} private: m_bflag;}; int main () {return 0;} This will not have errors when recompilated! Volatile Keyword Volatile is a freshly known keyword in C / C , which tells the compiler that do not hold a temporary copy of the variable, which can be applied to basic types such as int, char, long ... Also suitable for C's structure and C class. When the structure or class object is modified with Volatile, the structure or class is considered volatile. Using Volatile does not negate the need for critical_section, Mutex, Event, for example: int i; i = i 3; No matter how, there will always be a short period of time, i will be placed in a register because the arithmetic operation can only be done in the register. In general, the volatitle keyword is for rows between rows, not in the line. Let's first implement a simple function to observe the deficiencies in the assembly code produced by the compiler, and observe how the volatile keyword fixes this deficiencies. In this function, there is a busy loop (so-called busy loop is also called busy waits, is a cycle method of high waste CPU time) Void getKey (char * pch) {while (* pch == 0);} When you are in VC After the optimization option is turned off, compiling this program will be obtained (assembly code); while (* pch == 0) $ l27; load the address stored in Pch Mov EAX, DWORD PTR _PCH $ [EBP ]; Load The Character Into The Eax Register Movsx Eax, Byte Ptr [EAX]; Compare The Value To Zero Test Eax, Eax; if Not Zero, EXIT LOOP JNE $ L28; JMP $ 1 $ L28;} This paragraph is not optimized The code is constantly loaded into the appropriate address, the contents of the address, the test result.
The efficiency is quite low, but the result is very accurate now let's take a look at all the optimization options of the compiler open, recompilate the program, generated assembly code, and what is more different from the code above; {; loading Address Stored In Pch Mov Eax, DWORD PTR _PCH $ [ESP-4]; Load The Character INTO The Al Register Movsx Al, Byte Ptr [Eax]; While (* PCH == 0); Compare The Value In The Al Register To Zero Test Al, Al; if STILL ZERO, TRY JE SHORT $ L84 ;;} From the length of the code, it can be seen, which is much shorter than that is not optimized. It should be noted that the compiler puts the MOV instruction outside the loop. This is a very good optimization in a single-thread, however, in multi-threaded applications, if another thread changes the value of the variable, the loop will never end. The value being tested will always be placed in the register, so the segment code is a huge bug in the case of multithreading. The solution is to rewrite the getKey function and declare the parameter PCH as Volatile. The code is as follows: void getKey (Volatile Char * PCH) {while (* pch == 0);} This change is not optimized Any influence, please see the optimized results:; {; load the address store, {; DWORD PTR _PCH $ [ESP-4]; while (* pch == 0) $ l84:; Directly Compare The Value To Zero CMP Byte Ptr [EAX], 0; if STILL ZERO, TRY AGAIN JE SHORT $ L84 ;;} This time the modification results are relatively perfect, the address will not change, so the address declaration is moved outside the loop. The address content is Volatile, so it is constantly reconfined every cycle. Passing a const volatile variable is passed to a function to function. Such a statement means that the function cannot change the value of the variable, but the value of the variable can be changed by another thread at any time.