2010-09-21 36 views
5

在開關-case語句聲明,與初始化是無效的,但聲明,和當時的分配是允許的。如以下代碼片段所示。的switch-case:報關與 - 初始化和聲明,和當時的分配

編譯器端這兩種初始化類型有什麼區別?爲什麼第一種類型的初始化無效,第二種類型是有效的。

switch(val) 
{ 
case 0: 
    int newVal = 42; //Invalid 
    break; 
case 1: 
    int newVal2;  //Valid 
    newVal2 = 42; 
    break; 
case 2: 
    break; 
} 
+0

你使用什麼編譯器? – NullUserException 2010-09-21 05:16:29

+0

Visual Studio 2008 – 2010-09-22 11:30:48

回答

4

事實上,既不是合法的C++。除非它是作用不能在一個開關的情況下聲明一個變量:

switch(val) 
{ 
case 0: 
    { 
    int newVal = 42; // now valid 
    } 
    break; 
case 1: 
    { 
    int newVal2;  // still Valid 
    newVal2 = 42; 
    } 
    break; 
case 2: 
    break; 
} 

你的編譯器允許的情況下1事實是你的編譯器的缺陷,也可能延期。至少,根據標準。

+0

「int newVal2;」的聲明是有效的,因爲沒有初始值設定項。 – 2010-09-21 05:52:30

9

實際上,規則是您不能通過具有初始化的聲明(或超過非POD類型變量的聲明)跳到塊中。 C++標準規定:(C++ 03§6.7):

可以將其轉換爲塊,但不能以繞過具有初始化的聲明的方式。從具有自動存儲持續時間的局部變量不在範圍內的點跳轉到(77)的程序不適用於其範圍內的點,除非該變量具有POD類型(3.9),並且在沒有初始值設定項(8.5)。

(*)從switch聲明的條件轉移到case標籤被認爲是這方面的一個跳躍。

int newVal = 42;是具有一個初始化(在= 42部分)的聲明。該程序格式不正確,因爲如果val12,則會在初始化之後跳入切換塊。

int newVal2;也是聲明;因爲int是POD類型,並且聲明沒有初始化程序,所以您可以跳過此聲明。

+0

+1:我正在尋找這個,但找不到標準 – Chubsdad 2010-09-21 05:55:45

+0

好。這是因爲C++標準這麼說。但是同樣的理由是什麼。標準爲什麼這麼說。是不是很奇怪,int newVal = 42;不允許在哪裏作爲int newVal; newVal = 42;被允許? – 2010-09-22 11:37:14

+0

@Dahiya:這並不奇怪,初始化和賦值是不同的東西(對於大多數非POD類型,它們是各不相同的東西,因爲構造函數然後參與初始化)。例如,考慮一下你是否有'std :: string';如果你跳過它的聲明,變量是可訪問的,但其內容是未初始化的,因爲它的構造函數從未被調用過。 – 2010-09-22 14:18:01