2009年11月13日 星期五

GCC C++ Compiler 會聰明地幫你還原 const 變數的數值

關於前一篇文章 C++ Programming: Call by Reference/Value/Pointer and const_cast 所留下的問題
再寫一段簡單的程式碼來作實驗
/* main.cpp */
void funcA(const int &);
void funcB(int);
void funcC(const int *);

int main(int argc, char* argv[])
{
    const int value = 11;
    funcA(value);
    funcB(value);
    funcC(&value);
    funcB(value);
    return 0;
}

/* Call by Reference */
void funcA(const int& value)
{
    int& tmp = const_cast<int&>(value);
    tmp = 22;
}

/* Call by Value */
void funcB(int value)
{
    value = 33;
}

/* Call by Pointer */
void funcC(const int* value)
{
    int* tmp = const_cast<int*>(value);
    *tmp = 44;
}
這次利用 GCC 來產生 x86 的組合語言看看到底發生了什麼事情
$ g++ -S main.cpp
就會產生 main.s 檔案
來看看其中的片段
    call    _Z5funcARKi
    movl    $11, (%esp)
    call    _Z5funcBi
    leal    -8(%ebp), %eax
    movl    %eax, (%esp)
    call    _Z5funcCPKi
    movl    $11, (%esp)
    call    _Z5funcBi
答案是在呼叫完 funcA 跟 funcC 之後
GCC 聰明地將 value 的值給還原成 11 了
如果在 C++ 程式碼中第二次呼叫 funcB 給拿掉就不會看到第二個
    movl    $11, (%esp)
聰明的 GCC 只會在適當的時候幫你還原 const 變數的數值,造成 const 變數值從來沒被改變過的假象 :)
張貼留言