const int a = 1;
const int* p = &a;
auto q = const_cast<int*>(p);
cout << a << endl;
*q = 2;
cout << a << endl;
cout << *q << endl;
volatile const int b = 1;
volatile const int* t = &b;
auto r = const_cast<int*>(t);
cout << b << endl;
*r = 2;
cout << b << endl;
cout << *r << endl;
以上程序的輸出為
1
1
2
1
2
2
下面是具體分析:
對于const變量a,由指針p指向它,再由p得到非const的版本q以能夠改變它的值,接著使用q改變a的值,但是發(fā)現(xiàn)將2賦值給a時,此時直接輸出a的值仍是1,通過指針q輸出a的值卻是修改后的a的值(也就是2)。
這是因為C++編譯器對const變量進行了優(yōu)化,講const的a放在了編譯器的符號表中,這樣做的目的是讓取值操作變得更有效率,所以當(dāng)我們用q去改變a的值之后,a所在地址存儲的值確實改變了,但是符號表中的值沒有變,此時直接輸出a,輸出的是符號表中的,而通過指針q輸出的a才是真實的a的值。
對于第二部分,我們講變量都加上volatile,這樣每次訪問變量時會重新去存變量的地址處取值,所以此時直接輸出b的值是修改之后的真實的值,而不是符號表中存儲的值。
接著我試了一下指針常量是不是也是一樣的結(jié)果,發(fā)現(xiàn)當(dāng)指針是常量時,卻沒有以上的特性,也就是說編譯器沒有對指針常量進行優(yōu)化(沒有把它存在編譯器符號表中)。
注:以上環(huán)境vs2017,msvc。