C/C ++ key points (5)

Source: Internet
Author: User

 

Master the C/C ++ points (4 ).

 

 

13. mutable and volatile

These two keywords are rarely met. Learn embedded estimation to know the latter, and study C ++'s estimation to know the former.

(1) mutable

In C ++, mutable is set to break through the const restrictions. Variables modified by mutable will always be in a mutable state. Even if the struct variable or class object in a const function is const, its mutable member can be modified.

 

Struct ST

 

{

 

Int;

 

Mutable int B;

 

};

 

Const ST st = {1, 2 };

 

St. a = 11; // compilation Error

 

St. B = 22; // allow

Mutable can only modify non-static data members in the class. The use of mutable data members seems like a scam because it enables the const function to modify the data members of an object. However, the wise use of the mutable keyword can improve the code quality, because it allows you to hide implementation details from users without using uncertain things. We know that if the member function of the class does not change the state of the object, the member function will be declared as const. However, sometimes we need to modify some data members irrelevant to the class status in the const function, so this data member should be modified by mutalbe.

 

Class ST

 

{

 

Int;

 

Mutable int showCount;

 

Void Show () const;

 

...

 

};

 

ST: Show ()

 

{

 

... // Display code

 

A = 1; // error. Normal variables cannot be modified in the const member function.

 

ShowCount ++; // correct

 

}

 

Const promises that once a variable is modified, the value of this variable will not be changed under any circumstances as long as no forced conversion (const_cast) is used, the same is true for a function modified by const. Once a function is modified by const, it cannot directly or indirectly change the values of variables other than the function body, not even calling a function that may cause this change. This kind of commitment is also strictly guaranteed in syntax, and any behavior that may violate this promise will be checked by the compiler.

Mutable promises that if a variable is modified, the variable will always be in a mutable state, even in a const function. This form a symmetric definition with const. One is always the same, and the other is always the same.

To check whether a variable or function is const, you only need to check whether it is constant or invariant. to check whether a variable is mutable, you only need to check whether it is forever mutative.

There are three tangled problems:

1. Why is the member variable of the protection class not modified?

2. Why do I need to define a mutable keyword to break through the const Lock Line when using const to protect member variables?

3. Is it necessary to use the const and mutable keywords?

The member variables of the protection class are not modified in the member function to ensure the logic of the model is correct. By using the const keyword, the state of the class object cannot be modified incorrectly in the function. In addition, the impact of using this member function can be predicted more accurately in all scenarios where this member function is used. Mutable is used to break through the lock line of const, so that some secondary or auxiliary member variables of the class can be changed at any time. The const and mutable keywords are not used. The const and mutable keywords only give modeling tools more design constraints and design flexibility, in addition, programmers can give more logic check problems to compilers and modeling tools to relieve the burden on programmers.

(2) volatile

Like const, volatile is a type modifier. For volatile-modified data, the compiler cannot optimize its execution period stored in registers. This feature is designed to meet special needs such as multi-thread synchronization, interrupt, and hardware programming. When the variable declared by this keyword is encountered, the compiler will not optimize the code that accesses the variable, so as to provide direct access to the special address.

Volatile was originally intended to be "changeable", but this interpretation is a bit misleading and should be interpreted as "direct access to the original memory address" is more appropriate. "Easy to change" is an unknown change in the value of a common variable in terms of the compiler (optimization function) (that is, it is not a situation where the value is changed by executing the code assignment ), it is caused by external factors, such as multithreading and interruptions. When the compiler is optimizing, it sometimes retrieves some values and directly accesses them from the registers rather than from the memory. This optimization is no problem in a single-threaded program, however, in a multi-threaded program, because multiple threads run concurrently, it is possible that a thread has changed a public variable, and the value of registers in other threads has expired, but this thread itself does not know, think that there is no change, still get from the register, it will cause the program to run undefined behavior. It is not because the variable modified with volatile is "changeable". If there is no external cause, it will not change if it is defined with volatile. With the variable modified by volatile, the compiler will not optimize its related code, but generate the corresponding code to directly access the original memory address.

Generally, volatile is used in the following areas:

1. volatile must be added to the variable modified in the interrupted service program for testing by other programs;

2. volatile should be added to the labels shared by all tasks in a multi-task environment;

3. volatile is also required for memory-mapped hardware registers, because each read/write operation may have different meanings;

An example of using this keyword is as follows:

 

Volatile int I = 10;

 

Int a = I;

 

...

 

// Other code that does not explicitly tell the compiler to perform operations on I

 

Int B = I;

 

Volatile indicates that I may change at any time and must be read from the I address each time it is used, therefore, the compilation code generated by the compiler will read data from the I address again and put it in B. The optimization method is that because the compiler finds that the code between the two data reads from I has not performed any operations on I, it will automatically take the data read from the last time (that is, 10) put it in B, instead of re-reading from I. In this way, if I is a register variable or indicates a port data, it is prone to errors, so volatile can ensure direct access to special addresses.

 

// Addr is the volatile variable.

Addr = 0x57;

Addr = 0x58;

If the preceding two statements perform different operations on the external hardware, the compiler cannot optimize the preceding statements just as it treats a Common Program and considers "addr = 0x58; while ignoring the first statement (that is, only one machine code is generated), the compiler will compile one by one and generate the corresponding machine code (two ).

Volatile is always related to optimization. the compiler has a technology called data stream analysis, which analyzes where variables are assigned, where they are used, and where they are invalid. The analysis results can be used for constant merging, constant propagation optimization, further eliminating code. But sometimes these optimizations are not required by the program. In this case, you can use the volatile keyword to disable these optimizations. They have the following functions:

1. volatile variables are not cached in registers between two operations. In a multi-task or interrupt environment, variables may be changed by other programs, and the compiler itself cannot know them. volatile tells the compiler this situation.

2. Constant merging, constant propagation, and other optimizations are not performed. Therefore, the if condition, like the following code, is not considered unconditional.

 

Volatile int I = 1;

If (I> 0)

...

3. Read and Write volatile variables will not be optimized. If you assign values to a variable but do not use them later, the compiler can often omit the assignment operation. However, the processing of Memory Mapped IO cannot be optimized like this.

 

From tht's column

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.