2016-07-22 44 views
3

在將傳統項目升級到VS2015時,我注意到有很多錯誤,例如在函數內部重新定義了局部變量。重新定義/遮蔽局部變量有多糟?

void fun() 
{ 
    int count = applesCount(); 

    cout << "Apples cost= " << count * 1.25; 

    for (int bag=0; bag<5;bag++) 
    { 
     int count = orangesCount(bag); 

     cout << "Oranges cost = " << count * 0.75; 
    } 
} 

由編譯器錯誤/警告消息:

declaration of 'count' hides previous local declaration 

我知道這顯然是不使用相同的名稱變量count一個很好的做法,但可以在編譯器真的把事情搞得一團糟,以及或者他們通常會優雅地處理這種情況?

是否值得更改和修正變量名稱,或不太可能造成任何傷害,風險低或無風險?

+1

是 - 原因很簡單 - 爲什麼讓生活更難比需要 –

+0

我猜它的一個錯誤,如果你建立時打開警告視爲錯誤標誌。 – Arunmu

+0

無論如何'count'對於一個變量來說都不是一個好名字 –

回答

9

我注意到有很多錯誤,例如在函數內重新定義了一個局部變量。

您沒有在演示重新定義這裏。您將顯示一個變量shadowing的示例。

可變陰影在句法上不是錯誤。它是有效的和明確的。但是,如果您的意圖是使用外部範圍的變量,那麼您可以認爲它是一個邏輯錯誤。

,但可以在編譯器真的把事情搞得一團糟

與陰影的問題編號爲,它可以是很難跟蹤的爲程序員。編譯器是微不足道的。你可以在這個網站上找到很多問題,這些問題源於陰影變量引起的混淆。

在這個小函數中挖掘哪個表達式使用哪個變量並不難,但想象一下函數是幾十行和幾個嵌套和連續的塊。如果該功能足夠長,以至於一眼就看不到不同範圍內的所有不同定義,則可能會造成誤解。

declaration of 'count' hides previous local declaration 

這是一個很有益的編譯器警告。你沒有用完名字,爲什麼不給函數中的所有局部變量賦一個唯一的名字?但是,不需要將此警告視爲錯誤。這僅僅是一個提高你程序可讀性的建議。

在此特定示例中,在內部作用域打開後,外部作用域中不需要count,因此您可以重複使用兩個計數的一個變量。

是否值得改變和修正變量名

取決於你是否更看重短期的工作量與長期。更改代碼以使用唯一的描述性局部變量名稱現在是「額外」工作,但每次有人必須在稍後瞭解該程序時,不必要的陰影會增加精神挑戰。

+0

是的影子,這就是我的意思。 – zar

2

恕我直言,不好的編碼習慣。很難保持和閱讀。

編譯器可以區分外部變量和內部變量。

有了良好的詞彙表(和詞庫),人們不需要使用相同的變量名稱。

1

以我的經驗,編譯器通常很優雅地處理這個問題。但是,它是肯定是不好的做法,除非你有一個非常有說服力的理由這樣做,否則你應該重新使用舊的變量(如果它在邏輯上是有意義的),或者聲明一個[不同的 - 命名]新變量。

+1

希望不只是「通常」。該行爲已被很好地定義,所以編譯器不會做正確的事情是一個錯誤的編譯器。 –

2

隱藏一個變量(這是什麼)具有完全明確的語義,所以編譯器不會弄亂它。它將完全按照所告知的進行,並具有明確的結果。

問題是(往往是這樣)與人類。在閱讀和修改代碼時犯錯很容易。如果一個人不是很小心,跟蹤哪個名字被引用的變量可能會非常棘手,並且很容易在你認爲你正在修改的地方犯錯誤,但實際上你正在修改另一個。

所以編譯器很好,程序員就是這個問題。

0

Zar,

編譯器會很好地處理這種情況。在您的示例中,count變量在兩個不同的作用域「{}」中定義。由於變量的範圍,彙編語言將引用堆棧上的兩個不同地址。第一個「計數」可能是堆棧點SP-8,而內部計數可能是SP-4。一旦轉換成地址,名稱就無關緊要。

我通常不會因文體原因而改變工作代碼。如果代碼亂七八糟,那麼你有冒險破壞它。通常凌亂的代碼沒有任何好的測試,所以很難知道你是否破壞了它。

如果您需要增強代碼,那麼當然會整理一下。

--Matt