2015-12-28 46 views
12

Các tiêu chuẩn như của N4567 cấm một số loại lại tuyên bố của một tên trước đó đã tuyên bố trong một điều kiện như sau-theo tiêu chuẩn (§3.3.3/4):Tiêu chuẩn có nghĩa là gì bởi "điều kiện tiếp theo của tuyên bố đó"?

Tên khai báo trong for-init-statement, khai báo phạm vi, và trong điều kiện của if, while, for, và các câu lệnh switch là local cho câu lệnh if, while, for, hoặc switch (bao gồm câu lệnh được kiểm soát), và sẽ không được redeclared trong điều kiện tiếp theo của câu lệnh đó cũng như trong khối ngoài cùng (hoặc, đối với câu lệnh if, bất kỳ khối ngoài cùng nào) của câu lệnh được kiểm soát; xem 6.4.

Tuy nhiên, xem xét thực tế rằng đoạn mã sau biên dịch tốt,

int main(void) { 
    if (int i=10) 
     if (int i=20) 
      ; 
    return 0; 
} 

có vẻ như không rõ ràng cho tôi những gì chính xác "một điều kiện tiếp theo đó tuyên bố" là viết tắt của.

+6

Có lẽ nó đề cập đến tình huống cho 'for':' cho (int i = 0; int i = 1;); '. Có một điều kiện tiếp theo sau khai báo ban đầu của 'i'. Các từ ngữ cho 'if' mặc dù," bất kỳ khối ngoài cùng ", chỉ ra rằng nó xem xét các chi nhánh khác của một' if' là một phần của 'if', vì vậy tôi nghĩ rằng nó cũng có thể đề cập đến' if (int i = 1); nếu if (int i = 1); '. –

+1

Tôi nghĩ rằng nó đang nói về việc tuyên bố một tên hai lần trong cùng một điều kiện. Đó là hai câu lệnh 'if' khác nhau với các điều kiện khác nhau. – Cornstalks

+0

Ah, cấu trúc là 'if (...) stmt; khác stmt', vì vậy tôi không nghĩ rằng ví dụ của tôi với hai ifs phù hợp. "bất kỳ khối ngoài cùng nào" được dự định rõ ràng để tham chiếu đến 'if (int i = 1) {int i = 2; } else {int i = 3; } 'và không cho' if (int i = 1); nếu if (...) {int i = 2; } '(IMO). –

Trả lời

2

khoanh tròn "rằng" tuyên bố có nghĩa là if, while, for, và switch tuyên bố rằng đã xác định tên, và không phải là substatement điều khiển bởi các điều kiện hoặc lặp.

này được giải thích:

6,4/3: Một tên được giới thiệu bởi một tuyên bố trong một điều kiện (hoặc được giới thiệu bởi các decl-specifier-seq hoặc tor declara- của tình trạng ) nằm trong phạm vi từ điểm tuyên bố cho đến khi kết thúc các câu lệnh con được kiểm soát bởi điều kiện. Nếu tên là được khai báo lại ở khối ngoài cùng của trạm biến áp được kiểm soát bởi điều kiện , thì tuyên bố tuyên bố lại tên đó là không đúng định dạng.

Đây là lý do tại sao Statment sau đây là hợp lệ:

if (int i=10) 
    if (int i=20) 
     ; 

Trình biên dịch phân tích việc kê khai của if (int i=20) không phải là một tình trạng khác nhau của cùng if-tuyên bố, nhưng như một substatement kiểm soát. Và như tuyên bố thứ hai của tôi diễn ra trong điều kiện, nó không được xem xét trong khối ngoài của câu lệnh được vẽ.

Ngược lại, báo cáo kết quả gần như tương đương sau đây là không hợp lệ, vì nó phá vỡ khối hạn chế bên ngoài:

if (int k=10) { 
    int k=20; // <===== ouch ! redefinition in the outerblock 
    if (k) 
     cout <<"oops"; 
} 

Do đó trường hợp duy nhất mà bạn có thể có một "điều kiện tiếp theo của rằng tuyên bố "là câu lệnh for. Các standandard nổi bật tình hình đặc biệt này, bằng cách đưa ra các lý do để các hạn chế mà bạn đã trích dẫn với một từ ngữ rõ ràng hơn:

6.5.3/1: (...) Tên khai báo trong cho-init-tuyên bốtrong cùng declarative vùng như những tuyên bố trong tình trạng này,

tức tuyên bố cùng tên trong init và trong điều kiện sẽ phá vỡ ODR .

+0

Tại sao không 'if (int i = 20)' đếm là khai báo lại tên trong khối ngoài cùng của substatement? –

+1

@ M.M bởi vì khi bạn khai báo biến trong điều kiện, nó có thể nhìn thấy trong điều kiện và câu lệnh được kiểm soát, nhưng không phải ở bên ngoài. Đây là lý do tại sao bạn không thể sử dụng lại các biến được khai báo trong init cho các statment như 'for (int i = ...) {...} nếu (i == ...) handle_special_case() ; 'trừ khi bạn sử dụng một số phần mở rộng không chuẩn mà tồn tại trên một số trình biên dịch để hỗ trợ mã kế thừa. – Christophe

+0

@ M.M [ở đây một ví dụ MSDN về mở rộng] (https://msdn.microsoft.com/en-us/library/84wcsx8x.aspx) liên quan đến phạm vi giới hạn của biến được xác định trong khởi tạo/điều kiện – Christophe

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