推 purpose: 我有在 Windows 用 g++ 編譯試過,const int 剛好被放在 02/09 00:08
→ purpose: 唯讀記憶體,所以有碰過改完 Runtime 當掉的狀況。 02/09 00:09
→ purpose: 至於 x 還是 1 沒變 5566,那是編譯器在編譯時,就直接 02/09 00:10
→ purpose: 把值寫死成 1,他不會在 Runtime 重新讀取 x 的內容 02/09 00:10
→ RealJack: 我覺得還是有點問題,編譯會直接寫死應該只有巨集之類才 02/09 15:04
→ uranusjr: @RealJack 世界上有個技術叫最佳化 02/09 15:05
→ RealJack: 會發生,我把const全部去掉後發現內建type的值會改變 02/09 15:06
→ RealJack: 然後用objdump比較這兩個.o檔,發現組語都一樣 02/09 15:07
→ RealJack: 這樣要如何解釋加const和沒有const的行為會不一樣呢? 02/09 15:08
推 dirkc: 其實改了,只是之後用到符號x的時候極可能會直接置換成常數1 02/09 15:36
→ dirkc: 改成int y=1;const int x=y;或volatile const int x=1; 02/09 15:37
→ dirkc: 就會看出一樓說的差別,因為會強制使用可讀寫位址存放x 02/09 15:38
→ dirkc: 編譯器也不會把符號x置換成常數1 02/09 15:38
→ dirkc: @RJ 你把x丟入函式(例如printf)再看組語就知道 02/09 15:42
→ dirkc: 丟x和丟*p是不同結果,因為x可能會直接被置換成常數 02/09 15:43
→ dirkc: const這個字在執行期沒有意義,執行後只看memory protection 02/09 15:55
→ dirkc: 本質上不是效率考量,精確說是根本不考量 02/09 15:56
→ RealJack: 我先研究一下好了...背後有很多些東西要釐清@@ 02/09 18:24
→ RealJack: 再請教一下要如何確定變數被放在唯讀的記憶體區塊,感謝! 02/09 18:25
→ purpose: 位址後,這個 debugger 有提供記憶體分佈資訊,其中的 02/09 18:30
→ purpose: 00409000 起始位址這項目,它的存取欄位只有寫 R 就唯讀 02/09 18:31
推 dirkc: 通常要確定就是用debugger去看編譯後結果,像樓上的反組譯 02/10 09:53
→ dirkc: 顯示x存在0x409050,p則是用堆疊esp+1c的位址;然後現在os基 02/10 09:55
→ dirkc: 本上除了堆疊和堆積幾乎都是唯讀,也可以用debugger查詢 02/10 10:07
→ dirkc: 怎麼配是編譯器的決定,不過字面常數或全域const容易配唯讀 02/10 10:09
→ dirkc: 應該說怎麼配是編譯器的初稿,os的定案;編譯器決定位置,os可 02/10 10:16
→ dirkc: 決定rwx讀寫執行權限,也可能修改區塊基底位址(ASLR) 02/10 10:17
→ dirkc: (這裡說的編譯器指的是同時有編譯,組譯,連結功能的程式) 02/10 10:25
→ dirkc: 有點想說通常寫程式不用去探究這些;今天就是因為某種程度 02/10 10:40
→ dirkc: 而言欺騙了編譯器(先告訴它const而後又要去改),既然越過了 02/10 10:41
→ dirkc: 編譯器,就需要更底層的資訊來解釋發生的現象 02/10 10:42