前段時間,發現同一段c++**在windows 、linux下的執行結果居然不一樣,於是測試了一把。
我們都知道,c++中不同作用域中不同的變數是互不干擾的,可以在全域性作用域、函式作用域宣告同樣名字的名字。區域性作用域中的變數只在區域性作用域中生效,在區域性作用域之外是不可見的。
但在for語句中宣告的變數,屬於for語句所定義的區域性作用域嗎?
實驗環境
visual stuio:visual studio2015; release版本;x86平台
g++:debian 4.9.2-10;編譯命令 g++ -std=c++11 test_para.cpp -o test_para
實驗一
**:
#include void test_para(inti) std::cout
<< a << "
final
"<< &a <}int
main()
windows執行結果:
0 0030fae8linux執行結果1 0030fae8
2 0030fae8
00c61040 final 00c61040
編譯失敗按照我的認知,在for語句中定義的變數屬於區域性變數,因此離開for語句塊之後變數應該是不可見的,linux下g++的編譯結果正是如此,a在函式作用域沒有宣告。window下的結果就比較詭異,a既不是for語句種的『a'(位址不同),而且a的值與a的位址居然是一樣的,maybe undefined。error: 'a' was not declared in this scope
實驗二
**:
#include void test_para(inta) std::cout
<< a << "
final
"<< &a <}int
main()
windows執行結果
0 0045f93clinux執行結果1 0045f93c
2 0045f93c
1 final 0045f940
0 0x7ffda0098e9c注意,**與實驗一的**差異非常小,僅僅是test_para的形參名也叫』a『,與for語種的區域性變數重名。在這段**中,linux和windows的結果是一樣的:函式作用域的『a』與for語句種的『a'是互不干擾的兩個變數。1 0x7ffda0098e9c
2 0x7ffda0098e9c
1 final 0x7ffda0098e8c
實驗三
**:
#include void test_para(inta) std::cout
<< a << "
final
"<< &a <}int
main()
windows執行結果
0 0035fd74linux執行結果1 0035fd74
2 0035fd74
1 final 0035fd8
0 0x7ffe4838156c實驗三的**與實驗二的**區別也很小,僅僅是for語句中直接使用了』a',而沒有定義『a'(沒有寫成int a)。在windows上,可以看到在函式作用域的』a'與for語句中的『a'是兩個不同的變數(位址不同),但for語句塊種的並沒有定義啊,感覺是visual studio自行加了乙個auto,將 for (a = 0; a <= 2; a++) 變成了 for (auto a = 0; a <= 2; a++)1 0x7ffe4838156c
2 0x7ffe4838156c
3 final 0x7ffe4838156c
在linux上,函式作用域的』a'與for語句中的『a'是同乙個變數,這是比較符合常理的,既然for語句塊中用到了變數『a',又沒有宣告,那麼自然應該在上一級作用域種查詢,也就是找到了函式作用域種的』a'
總結
可以看到,三次實驗中,只有第二次實驗windows(vs)與linux(g++)表現是一致的,第一次實驗與第三次實驗,windows上的執行結果都不太符合預期,特別是實驗三,感覺visual studio有點畫蛇添足。不過,我也沒有查到權威資料,不知道windows linux在這個問題上的差異性是不是因為本身就是undefined,也許通過看彙編也能看出一些端倪。日常工作中如果要考慮平台相容性,最好是比較明確的寫法,比如這裡,函式形參和語句塊中的區域性變數就不要用同樣的名字好了。
G 與VS2015在變數作用域上的差異性
前段時間,發現同一段c 在windows linux下的執行結果居然不一樣,於是測試了一把。我們都知道,c 中不同作用域中不同的變數是互不干擾的,可以在全域性作用域 函式作用域宣告同樣名字的名字。區域性作用域中的變數只在區域性作用域中生效,在區域性作用域之外是不可見的。但在for語句中宣告的變數,屬...
rtmpdump在vs2015下的編譯
這裡就不對編譯錯誤進行截圖了,直接上解決方案。第一步修改rtmp sys.h檔案,將 win32巨集下 的內容修改為以下內容 include include if defined msc ver msc ver 1900 msvc define snprintf snprintf define vs...
GDAL在VS2015上編譯及常見錯誤分析
說實話,gdal在windows上的編譯真的讓人頭疼,它有各種版本的問題,以前用vs2010編譯過一次,這次又一次搞了好久。因此記錄以來,常見的錯誤點。a.其他版本的應該也可以,這裡可以看一下nmake.opt檔案中是否支援vs2015 b.開啟nmake.opt檔案,將win64 yes前的 去掉...