G++與VS2015在變量作用域上的差異性


   前段時間,發現同一段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 <iostream>

void test_para(int i){
    for (int a = 0; a <= 2; a++) {
        std::cout << a <<" "<<&a <<std::endl;
    }
    std::cout << a << "  final " << &a << std::endl;
}

int main(){
    test_para(1);
    return 0;
}

  windows運行結果:

0 0030FAE8
1 0030FAE8
2 0030FAE8
00C61040  final 00C61040

  Linux運行結果

編譯失敗

error: 'a' was not declared in this scope

  按照我的認知,在for語句中定義的變量屬於局部變量,因此離開for語句塊之后變量應該是不可見的,Linux下G++的編譯結果正是如此,a在函數作用域沒有聲明。WIndow下的結果就比較詭異,a既不是for語句種的‘a'(地址不同),而且a的值與a的地址居然是一樣的,maybe undefined。

 

實驗二

  代碼:

#include <iostream>

void test_para(int a){
    for (int a = 0; a <= 2; a++) {
        std::cout << a <<" "<<&a <<std::endl;
    }
    std::cout << a << "  final " << &a << std::endl;
}

int main(){
    test_para(1);
    return 0;
}

 

  windows運行結果

0 0045F93C
1 0045F93C
2 0045F93C
1  final 0045F940

  Linux運行結果

0 0x7ffda0098e9c
1 0x7ffda0098e9c
2 0x7ffda0098e9c
1  final 0x7ffda0098e8c

  注意,代碼與實驗一的代碼差異非常小,僅僅是test_para的形參名也叫’a‘,與for語種的局部變量重名。在這段代碼中,Linux和Windows的結果是一樣的:函數作用域的‘a’與for語句種的‘a'是互不干擾的兩個變量。

 

實驗三

  代碼:

#include <iostream>

void test_para(int a){
    for (a = 0; a <= 2; a++) {
        std::cout << a <<" "<<&a <<std::endl;
    }
    std::cout << a << "  final " << &a << std::endl;
}

int main(){
    test_para(1);
    return 0;
}

 

  windows運行結果

0 0035FD74
1 0035FD74
2 0035FD74
1  final 0035FD8

  Linux運行結果

0 0x7ffe4838156c
1 0x7ffe4838156c
2 0x7ffe4838156c
3  final 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++)

  在Linux上,函數作用域的’a'與for語句中的‘a'是同一個變量,這是比較符合常理的,既然for語句塊中用到了變量‘a',又沒有聲明,那么自然應該在上一級作用域種查找,也就是找到了函數作用域種的’a'

 

 

總結

  可以看到,三次實驗中,只有第二次實驗Windows(vs)與Linux(g++)表現是一致的,第一次實驗與第三次實驗,Windows上的運行結果都不太符合預期,特別是實驗三,感覺visual studio有點畫蛇添足。不過,我也沒有查到權威資料,不知道windows linux在這個問題上的差異性是不是因為本身就是undefined,也許通過看匯編也能看出一些端倪。日常工作中如果要考慮平台兼容性,最好是比較明確的寫法,比如這里,函數形參和語句塊中的局部變量就不要用同樣的名字好了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM