2010-09-21 42 views
5

Trong báo cáo chuyển đổi trường hợp khai báo-với-khởi tạo không hợp lệ nhưng khai báo và phân công được cho phép. Như được hiển thị trong đoạn mã sau.Switch-Case: khai báo với khởi tạo và khai báo và sau đó gán

Sự khác nhau giữa hai kiểu khởi tạo này từ phía trình biên dịch là gì? Và tại sao loại khởi tạo không hợp lệ đầu tiên và loại thứ hai là hợp lệ.

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

Bạn đang sử dụng trình biên dịch nào? – NullUserException

+0

Visual Studio 2008 –

Trả lời

4

Thực tế, không phải là C++ hợp pháp. Bạn không thể khai báo một biến trong trường hợp chuyển đổi trừ khi nó có phạm vi:

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

Thực tế là trình biên dịch của bạn cho phép trường hợp 1 là lỗi của trình biên dịch hoặc có thể là phần mở rộng. Ít nhất, theo tiêu chuẩn.

+0

Khai báo 'int newVal2;' là hợp lệ vì không có bộ khởi tạo. –

9

Có hiệu lực, quy tắc là bạn không thể nhảy vào khối qua tuyên bố có khởi tạo (hoặc quá khứ khai báo biến loại không phải POD). Tiêu chuẩn C++ nói (C++ 03 §6.7):

Có thể chuyển thành một khối, nhưng không thể bỏ qua các khai báo với khởi tạo. Một chương trình nhảy (77) từ một điểm trong đó biến cục bộ có thời lượng lưu trữ tự động không nằm trong phạm vi đến điểm nằm trong phạm vi không đúng định dạng trừ khi biến có loại POD (3.9) và được khai báo không có bộ khởi tạo (8.5).

(*) Việc chuyển từ điều kiện của tuyên bố switch sang nhãn case được coi là bước nhảy về mặt này.

int newVal = 42; là khai báo có bộ khởi tạo (phần = 42). Chương trình không đúng định dạng vì nếu val1 hoặc 2, bạn sẽ chuyển sang khối chuyển đổi trong quá trình khởi tạo.

int newVal2; cũng là một tuyên bố; vì int là loại POD và khai báo không có bộ khởi tạo, bạn có thể nhảy qua tuyên bố này.

+0

+1: Tôi đã tìm kiếm điều này nhưng không thể tìm thấy trong tiêu chuẩn – Chubsdad

+0

OK. Nó là như vậy bởi vì C + + Standard nói như vậy. Nhưng những gì là hợp lý đằng sau giống nhau. Tại sao tiêu chuẩn lại nói vậy. Không phải là nó lạ mà int newVal = 42; không được cho phép ở đâu như int newVal; newVal = 42; được cho phép? –

+0

@Dahiya: Không lạ gì; khởi tạo và phân công là những thứ khác nhau (chúng là _very_ những thứ khác nhau cho hầu hết các loại không phải POD, vì các nhà xây dựng sau đó được tham gia vào việc khởi tạo). Hãy xem xét, ví dụ, nếu bạn có một 'std :: string'; nếu bạn nhảy qua khai báo của nó, biến có thể truy cập được nhưng nội dung của nó không được khởi tạo vì hàm tạo của nó chưa bao giờ được gọi. –

Các vấn đề liên quan