2013-03-24 47 views

Trả lời

8

Không, hành vi của một tuyên bố for (;;) được xác định rõ trong C.

N1570, đó là cơ bản giống với chính thức tiêu chuẩn ISO 2011 C, nói, trong phần 6.8.5 đoạn 6:

một tuyên bố lặp mà kiểm soát biểu hiện không phải là một biểu thức hằng số, mà không thực hiện các hoạt động đầu vào/đầu ra, không truy cập vào đối tượng không ổn định, và thực hiện không đồng bộ hóa hoặc nguyên tử hoạt động trong cơ thể, kiểm soát biểu thức hoặc (trong trường hợp của cho câu hỏi ) biểu thức-3, có thể được giả định bởi việc triển khai để chấm dứt.

với hai chú thích:

Một biểu thức điều khiển bỏ qua được thay thế bằng một hằng số khác không, mà là một biểu hiện thường xuyên.

Điều này nhằm mục đích cho phép các phép biến đổi trình biên dịch chẳng hạn như loại bỏ các vòng trống rỗng ngay cả khi không thể xác minh được kết thúc.

Chú thích đầu tiên cho thấy rõ ràng rằng for (;;) được coi là có biểu thức kiểm soát liên tục.

Điểm của quy tắc là cho phép tối ưu hóa khi trình biên dịch không thể chứng minh rằng vòng lặp kết thúc. Nhưng nếu biểu thức điều khiển không đổi, thì trình biên dịch có thể chứng minh một cách trivially rằng vòng lặp đó không hoặc không kết thúc, do đó không cần sự cho phép bổ sung.

+0

* "Điểm của quy tắc là cho phép tối ưu hóa khi trình biên dịch không thể chứng minh nhưng nếu biểu thức điều khiển là không đổi, thì trình biên dịch có thể chứng minh một cách trivially rằng vòng lặp hiện có hoặc không kết thúc. "* Tôi muốn đồng ý, nhưng sau đó tại sao' while (1); 'không được xác định trong C++? Sẽ không cùng một lý do áp dụng? – Mehrdad

+0

@Mehrdad: IMHO nên, nhưng tiêu chuẩn C++ không loại trừ các biểu thức kiểm soát liên tục từ phiên bản quy tắc của nó. –

+1

Chỉ cần chắc chắn để nắm bắt tất cả những gì có nghĩa là: trong C bạn có thể viết một chương trình mà logic được thực hiện hoàn toàn với bộ xử lý tín hiệu và có chương trình ngồi trong một vòng lặp vô hạn để chờ một sự kiện. Điều này nghe có vẻ không thực sự thông minh, nhưng tôi đồng ý rằng ngôn ngữ không nên cấm điều này. Trong C++ điều này sẽ bị cấm? –

0

Lý giải cho câu hỏi này với sự liên quan đến C++ là không liên quan đến C. Mục 5.1.2.3p6 bang giới hạn để tối ưu hóa, và một trong số họ là:

Tại chấm dứt chương trình, tất cả dữ liệu ghi vào file sẽ giống hệt với kết quả thực hiện chương trình theo ngữ nghĩa trừu tượng sẽ được sản xuất.

Bây giờ câu hỏi trở thành "Dữ liệu nào sẽ thực hiện theo ngữ nghĩa trừu tượng đã tạo ra?". Giả sử một tín hiệu ngắt vòng lặp, chương trình có thể kết thúc rất tốt. Các ngữ nghĩa trừu tượng sẽ không tạo ra đầu ra trước khi tín hiệu đó được nâng lên. Nếu có, trình biên dịch có thể tối ưu hóa cách puts("Hello");.

+0

Để làm rõ, hãy xem xét những điều sau đây: một chương trình không có gì ngoài một vòng trống rỗng theo sau là 'puts (" Hello ");' được biên dịch và thực thi, 'kill' được sử dụng để gửi tín hiệu cho chương trình thoát ra, và chương trình một cách duyên dáng làm như vậy bằng cách gọi exit từ trình xử lý tín hiệu. UB, @Deduplicator ở đâu? Theo như tôi biết, tín hiệu UB duy nhất trong tín hiệu là nếu chương trình trả về từ một trong các tín hiệu tương ứng với các lỗi tính toán. Đó không phải là những gì xảy ra ở đây, tuy nhiên, kể từ khi xử lý tín hiệu gọi thoát, thay vì quay trở lại. Hãy trình bày thẳng vấn đề của bạn. – Sebivor

+0

'exit' thực hiện các trình xử lý thoát và thực hiện các thao tác khác, không được đảm bảo hoạt động. – Deduplicator

+0

@Deduplicator Bạn đang cố gắng nói với tôi rằng một trình biên dịch có thể không tối ưu hóa 'puts (" Hello "),' đi, bởi vì hành vi không xác định có thể có mặt trong một trong các trình xử lý ngoại vi? Hậu quả của hành vi không xác định trong một trình xử lý ngoại tuyến là ... không xác định. Làm cách nào để ngăn việc tối ưu hóa này diễn ra? – Sebivor

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