【C/C++】 C++暫存器優化

李春港 發表於 2021-03-08

作者:李春港
出處:https://www.cnblogs.com/lcgbk/p/14502076.html

一、前言

在c++中什麼情況下,當我們定義一個常量時,編譯器都做了哪些操作呢?首先讓我們看下一節的程式。

二、程式碼例項

#include<iostream>

using namespace std;

int main ()
{ 
int const tmp = 100; //定義常量tmp tmp不能修改 
int const* p = &tmp; //不能通過指標修改指向的值  
int* const q = const_cast<int*>(p); //去常屬性 可以通過指標修改指向的內容 
*q = 200; 
cout << tmp << " " << *p << " " << *q << endl; //列印變數的值 
cout << &tmp << endl << p << endl << q << endl; //列印變數地址 
return 0;
}

看了以上程式你覺得結果會是怎麼樣呢?

結果:

100 
200 
200
00556820
00556820
00556820

到這裡你會發現:為什麼怎麼地址一樣,但值卻不一樣呢?
我們就相當於和編譯器約定好了,我們不會去修改 tmp 的值,這個時候編譯器就會做一個優化,將 tmp 的值,放到暫存器裡面,然後讀取 tmp 時直接在暫存器裡面讀取,加快讀取速度。

所以出現以上情況是因為:tmp 讀取的是「暫存器」的值,p ,q讀取的是「記憶體」的值。

三、volatile作用

以上例項出現的情況,有時候我們並不希望這樣的情況出現,然而 volatile 可以為我們去除這樣的優化,使用該關鍵字,相當於告訴編譯器,這個關鍵字修飾的變數要到記憶體裡面去操作,不要直接從暫存器取值。

優化程式碼如下:

volatile int const tmp2 = 100;
volatile int const* pm = &tmp2;   //不能通過指標修改指向的值 
int* const qm = const_cast<int*>(pm); //q本身只讀  指向讀寫 
*qm = 200;
cout << tmp2 << " " << *pm << " " << *qm << endl;
cout << (void*)&tmp2 << endl << (void*)pm << endl << qm << endl;

列印結果:

200 
200 
200
00666820
00666820
00666820

這樣就不會出現地址一樣,數值不一樣的情況了,也是我們希望看到的結果。