2009年11月16日 星期一

GCC C++ Compiler 根本沒有還原 const 變數的數值,只不過先行代換掉使用 const 變數的地方。

延續前三篇文章的討論
C++ Programming: Call by Reference/Value/Pointer and const_cast
GCC C++ Compiler 會聰明地幫你還原 const 變數的數值
GCC C++ Compiler 對於 const 變數的處理到底會有多聰明呢?
這次實驗的程式碼如下
#include <iostream>

void foo(const int&);
void bar(const int&);

using namespace std;

int main(int argc, char* argv[])
{
    const int value = 11;
    cout << value << endl;
    foo(value);
    cout << value << endl;
    bar(value);
    cout << value << endl;
    cout << *(int*)&value << endl;
    return 0;
}

void foo(const int& value)
{
    int& tmp = const_cast<int&>(value);
    tmp = 22;
}

void bar(const int& value)
{
    cout << value << endl;
}
正如網友 jclin 提到的「我比較不相信 GCC 會幫你還原 const value 的作法. 只是 compiler 知道那是 const, 基於 optimization 的角度
還有 chihchun 提到的「main::value 是一個 alias, compiler (g++ 4.3.4) 會替換成 integral literal,但是依然會在 Stack 中配置此變數供人使用。
GCC C++ Compiler 只不過是把原始碼先轉換成以下這段
#include <iostream>

void foo(const int&);
void bar(const int&);

using namespace std;

int main(int argc, char* argv[])
{
    const int value = 11;
    cout << 11 << endl;
    foo(value);
    cout << 11 << endl;
    bar(value);
    cout << 11 << endl;
    cout << *(int*)&value << endl;
    return 0;
}

void foo(const int& value)
{
    int& tmp = const_cast<int&>(value);
    tmp = 22;
}

void bar(const int& value)
{
    cout << value << endl;
}
const 變數並不代表它無法被改變數值,透過 const_cast 還是可以改變數值的,只不過已經先被當作字面常數替換掉的地方,在 C++ 程式碼的運作上不是那麼容易瞭解。
張貼留言