2009-09-02 38 views
8

Sau khi thử tay của tôi tại Perl và một chút C, tôi đang cố gắng để tìm hiểu C + + và tôi đã bị sa lầy bởi các chi tiết và cạm bẫy. Hãy xem xét điều này: -C++: bối rối tuyên bố ngữ nghĩa

int x = 1; 
{ 
    int x = x; // garbage value of x 
} 
int const arr = 3; 
{ 
    int arr[arr]; // i am told this is perfectly valid and declares an array of 3 ints !! 
} 

Huh, Tại sao sự khác biệt?

Để làm rõ: Sử dụng cùng tên hợp lệ trong một trường hợp và không hợp lệ trong một trường hợp khác và không hợp lệ trong một trường hợp khác.

+1

Bạn có thể làm rõ câu hỏi của mình không? Bạn đang đề cập đến sự khác biệt nào? – trshiv

+0

Tôi sử dụng cùng một tên khi tryiing những thứ đơn giản như int x = x, nó không hợp lệ, tôi thử làm nó cho các cấu trúc phức tạp như int arr [arr] nó hợp lệ. Làm tôi bối rối. –

+0

Có lẽ điều này là hiển nhiên, nhưng bất kể mã trên có hợp lý với trình biên dịch hay không, do đó bạn khó có thể nhìn thấy nó trong mã hiện tại và không khôn ngoan để đưa nó vào của riêng bạn. – flies

Trả lời

14

Chào mừng bạn đến với vũ trụ của C++! Đối với câu hỏi của bạn, câu trả lời nằm trong một khái niệm gọi là 'Point-of-declaration'.

>>int x = 1; 
>>{ int x = x; } // garbage value of x 

Từ Mục: -3.3.1.1 (C++ Dự thảo Tiêu chuẩn) Điểm kê khai cho một tên là ngay sau khi declarator hoàn chỉnh của nó và trước khi khởi tạo của nó (nếu có), ngoại trừ được nêu dưới đây.

int x = 12; 
{ int x = x; } 

Ở đây; 'operator =' là trình khởi tạo. Bạn có thể nói rằng điểm khai báo cho 'x' chưa được đạt tới, vì vậy giá trị của 'x' không xác định.

>>int const arr = 3; 
>>{ int arr[arr]; } // i am told this is perfectly valid and declares an array of 3 ints !! 

Tại sao? Từ phần: -3.3.1.4 (Bản nháp chuẩn C++) Tên không phải địa phương vẫn hiển thị cho đến điểm khai báo tên địa phương ẩn nó. Ở đây, điểm tuyên bố đạt được tại ';' tính cách. Vì vậy, giá trị có thể nhìn thấy trước của 'arr' được sử dụng tức là = 3.

Ngoài ra, bạn có thể muốn biết rằng sau đây là hợp lệ: -

const int e = 2; 
{ enum { e = e }; } // enum e = 2 

Từ Mục: -Chapter-3.3.1.4 (Bản thảo chuẩn C++): - Điểm khai báo cho điều tra viên ngay sau định nghĩa của điều tra viên.

Nhưng, không làm điều này

const int Spades = 1, Clubs = 2, Hearts = 3, Diamonds = 4; 
enum Suits 
{ 
    Spades = Spades,  // error 
    Clubs,    // error 
    Hearts,    // error 
    Diamonds    // error 
}; 

Tại sao? Bởi vì điều tra viên được xuất khẩu đến phạm vi kèm theo của điều tra. Trong ví dụ trên, các bảng liệt kê Spades, Clubs, Hearts, và Diamonds được khai báo. Bởi vì các điều tra viên được xuất khẩu đến phạm vi bao quanh, chúng được coi là có phạm vi toàn cầu. Các định danh trong ví dụ đã được định nghĩa trong phạm vi toàn cục. Vì vậy, nó là một lỗi.

Để biết thêm chi tiết và cạm bẫy (:-)), đọc trên phần 3.3 'Vùng khai báo và phạm vi' từ Dự thảo Tiêu chuẩn C++, nếu bạn quan tâm, bạn có thể giữ bản pdf từ here (http://www.research.att.com/~bs/SC22-N-4411.pdf).

+1

Cảm ơn bạn đã giải thích, nhưng tại sao nó lại quá phức tạp? –

+0

Tôi nghĩ rằng "Bạn có thể nói rằng điểm tuyên bố cho 'x' chưa đạt được, vì vậy giá trị của 'x' là không xác định" là sai. Điểm tuyên bố đã đạt được, và đây là lý do tại sao 'x' là không xác định, bởi vì nó đã được khai báo, nhưng chưa được khởi tạo. – Gorpik

+3

Lý do các quy tắc cần phức tạp là các trình khai báo C++ * phức tạp. Có rất nhiều khả năng trong đó, kết hợp với rất nhiều khả năng tương thích ngược, không có sự ngắt quãng rõ ràng từ lịch sử C của nó (nơi mà công cụ này không được chỉ định khá giống như các trường hợp chính thức và cạnh như thế này thường đến trình biên dịch), và bạn nhận các quy tắc chuẩn C++. –

7

Trước tiên, trong thế giới thực, bạn nên sử dụng không phải vì nó gây nhầm lẫn, và thậm chí một vài giây để hiểu điểm tốt này là quá nhiều chất thải.

Phế liệu phần còn lại của câu trả lời của tôi - Abhay đã hiểu đúng và chi tiết hơn nhiều :)

+1

Trong khi không phải là một câu trả lời thực sự cho câu hỏi, nó được một upvote cho chủ nghĩa thực dụng. –

+0

+1 Tôi đồng ý với chủ nghĩa thực dụng của bạn :-). Nhưng tôi đoán O.P. như một người học đã được thực hiện bởi sự ngạc nhiên với bản chất của pitfall. – Abhay

+1

+1 Chỉ cần không bao giờ đưa mã như vậy vào hệ thống sản xuất. – sharptooth

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