2015-01-28 11 views
15

xem xét sau đây ví dụ cơ bản:Có bỏ qua tuyên bố trả về hành vi không xác định trong C89 (hay còn gọi là ANSI C)?

#include <stdio.h> 

int main(void) 
{ 
    printf("Hi there!\n"); 
} 

Liệu nó gọi hành vi undefined trong C89? Tôi đã cố gắng để có được một số ý nghĩa từ this question, nhưng hầu hết các câu trả lời upvoted cho rằng nó thực hiện xác định và chắc chắn không UB ở đây (với ý kiến ​​của Keith Thompson, có vẻ mâu thuẫn).

Các spec nói trong §3.16 Định nghĩa và công ước:

Nếu một “trách nhiệm” hay “thì không phải là” yêu cầu xuất hiện bên ngoài của một chế bị vi phạm. hành vi không xác định. Hành vi không xác định được quy định khác trong Tiêu chuẩn này theo các từ “hành vi không xác định” hoặc bằng cách bỏ sót bất kỳ định nghĩa rõ ràng nào về hành vi . Không có sự khác biệt nào về sự nhấn mạnh giữa ba điều này: chúng tất cả đều mô tả “hành vi không xác định”.

và §5.1.2.2.3 chấm dứt chương trình :

Một trở về từ các cuộc gọi ban đầu để các main chức năng tương đương với gọi exit chức năng với giá trị được trả về bởi các main chức năng làm đối số của nó. Nếu chức năng main thực thi khoản hoàn trả chỉ định không có giá trị, trạng thái chấm dứt được trả về môi trường máy chủ là không xác định.

Hiểu biết của tôi là sau này không bao gồm trường hợp mất trả lại, như câu hỏi return không bao giờ được gọi, do đó, điều khoản phụ được áp dụng trước đây.

đọc Tuy nhiên thêm tác chỉ ra một cái gì đó khác nhau, §6.6.6.4 Các return tuyên bố:

Nếu một tuyên bố return mà không có một biểu hiện được thực thi, và giá trị của cuộc gọi chức năng được sử dụng bởi người gọi , hành vi không xác định. Tiếp cận } kết thúc chức năng tương đương với việc thực hiện câu lệnh return mà không có biểu thức.

Ok, vì vậy bây giờ 5.1.2.2.3 phân lớp được áp dụng:

Nếu main chức năng thực hiện một sự trở lại mà xác định không có giá trị. trạng thái chấm dứt được trả về môi trường máy chủ là không xác định.

Thuật ngữ "trạng thái chấm dứt là undefined" dường như không được UB, và cũng không bất kỳ hành vi cụ thể, nhưng nhiều hơn như đó là ngoài phạm vi C Standard, nghĩ nhiều hơn như: "để cho các môi trường máy chủ được lo lắng, chúng ta rửa tay từ đây ". Đó là sự giải thích chính xác?

+1

Nếu bạn chưa thấy nó, dưới đây là một số câu trả lời thú vị: http: // stackoverflow.com/q/204476/3933332 – Rizier123

+1

[Bản nháp đi tới C89 của tôi] (http://port70.net/~nsz/c/c89/c89-draft.html) không khớp với dấu ngoặc kép bạn ' đã đưa ra. Các số phần là hoàn toàn khác nhau, và các văn bản tương ứng khác nhau là tốt. Tất nhiên, nó là một dự thảo, không phải là tiêu chuẩn cuối cùng. Tuy nhiên, chúng tôi không thể đồng ý trả lời nếu chúng tôi không đồng ý về tiêu chuẩn này. –

+2

Tôi sẽ đọc đó là nói rằng nó tương đương với việc gọi 'return' không có biểu thức, sau đó cho mỗi' §5.1.2.2.3' nói rằng 'return' không có biểu thức kết quả trong một mã trả về không xác định cho hệ điều hành chủ. Bạn nói đúng, đây không phải là hành vi không xác định khi nói, vì những gì xảy ra được biết và luôn giống nhau; chương trình sẽ chấm dứt và một giá trị sẽ được trả lại cho hệ điều hành dưới dạng mã trả về. What * is * undefined là giá trị đó sẽ là gì. Vì vậy, có, tôi sẽ nói cách giải thích của bạn là chính xác. – aruisdante

Trả lời

4

Năm trước, tôi thực sự đã gỡ lỗi các vấn đề gây ra bởi điều này. Nó thậm chí còn thú vị hơn nếu bạn có một số đường dẫn mã với trả về và các đường dẫn khác mà không có.

Khi @aruisdante phỏng đoán trong nhận xét, hành vi được hiển thị thực sự là 'không xác định', nhưng phần không xác định duy nhất là giá trị được trả về (không giống như nhiều tình huống 'không xác định' khác có thể làm hỏng chương trình).

Những ngày này thực sự là một rủi ro bảo mật vì giá trị 'không xác định' được trả về thường là bất kỳ điều gì xảy ra trong thanh ghi CPU thường được sử dụng để trả về giá trị (hoặc trên ngăn xếp trong một số triển khai). để rò rỉ dữ liệu nhạy cảm.

+0

Bạn có đề cập đến chức năng 'main' cụ thể hay một hàm bình thường không? – Rufflewind

+0

IIRC, nó là 'chính', nhưng nó đã trở lại vào đầu những năm 90. Đó là một thời gian dài trước đây. – James

2

Tôi tin rằng ý định của Ủy ban tiêu chuẩn là giá trị trạng thái chấm dứt này không được chỉ định.

Theo N739 dự thảo:

và thay đổi câu cuối cùng của 5.1.2.2.3 phân lớp từ:

Nếu chính/chức năng/thực hiện một sự trở lại mà xác định không có giá trị, việc chấm dứt trạng thái được trả về môi trường máy chủ là không xác định.

tới:

Nếu/main/function thực hiện trả về không chỉ định giá trị, | trạng thái chấm dứt được trả về môi trường máy chủ là không xác định.

[Khái niệm về giá trị không xác định được một cách cẩn thận tránh những nơi khác.]

Bạn cũng có thể tìm thấy trong tiêu chuẩn hơn nữa, thuật ngữ đã được thay đổi và thuật ngữ "không xác định" được sử dụng do đó.

Tôi sẽ nói rằng nó chắc chắn không có ý định trở thành hành vi không xác định, nhưng vẫn không thể quyết định xem đó là hành vi không xác định hoặc như tôi đã nói không có hành vi nào cả. trích đoạn khác, điều đó sẽ cho thấy sau này là §1 Phạm vi:

tiêu chuẩn quốc tế này không nêu rõ:

  • cơ chế mà các chương trình C được gọi để sử dụng bởi một hệ thống xử lý dữ liệu ;

Tôi hy vọng điều này cũng có nghĩa là tiêu chuẩn này không chỉ định trạng thái chấm dứt của chương trình được xử lý bởi môi trường máy chủ.

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