Nơi nào đã thoát ra (-1).


22

Tôi thấy trong rất nhiều phần mềm kế thừa và hướng dẫn xấu trên Internet mà khuyên bạn sử dụng exit(-1), return -1hoặc tương tự để đại diện cho "chấm dứt bất thường". Vấn đề là, trong POSIX ít nhất, -1chưa bao giờ và không phải là mã trạng thái hợp lệ. man 3 exitminh họa rằng exit()trả về giá trị của status & 0377cha mẹ, có nghĩa là -1trở thành 255. Trên các hệ thống không phải POSIX, EXIT_FAILUREđược khuyến nghị cho tính di động. Nhưng tôi không bao giờ thấy "-1 có nghĩa là chấm dứt bất thường" kết hợp với "EXIT_FAILURE có thể là một cái gì đó khác với 1", cho thấy rằng họ tin rõ ràng "-1" là thông thường ngay cả trên các hệ thống không phải POSIX.

Đây là một ví dụ về câu hỏi StackOverflow khắc phục điều này. Phần mềm "unrealircd" cũng là một ví dụ về chương trình sử dụng exit(-1)để chấm dứt chương trình. Trong thực tế, điều này gây khó khăn cho giao diện systemd.

Trường hợp chống mẫu này đến từ đâu? Có hợp lệ trong một số bối cảnh?


1
"Các hệ thống giống như Unix có một quy ước mạnh mẽ rằng trạng thái thoát là 0 biểu thị thành công và bất kỳ trạng thái thoát khác không nào cũng biểu thị sự thất bại ... Quy ước này khá khó khăn khi kết nối với hệ vỏ Unix ..." ( Trạng thái thoát khác không để thoát sạch )
gnat

@gnat Theo hướng dẫn libc , trạng thái thoát rõ ràng là 0 đến 255. Nếu có câu trả lời ở đâu đó nói rằng các giá trị âm ở một điểm hợp lệ, tôi sẽ chấp nhận điều đó, nhưng tôi thấy điều đó rất đáng nghi ngờ.
dùng222973

1
@gnat "255" dễ dàng phù hợp với một unsigned char.
dùng222973


1
@gnat Một byte trong "Java" không phải là một ký tự không dấu, nó tương đương với một charvì các giá trị của nó là -128 đến 127. Hơn nữa, tôi đã nói "-1" được chuyển đổi thành "255" trong thân câu hỏi của tôi .
dùng222973

Câu trả lời:


20

Hầu như tất cả các máy tính Unix đều sử dụng twos-bổ trợ cho các số nguyên và trong twos-bổ sung -1 luôn là "tất cả các bit 1" bất kể kích thước từ. Nếu bạn muốn mã thoát lớn nhất có thể, bất kể kích thước của trạng thái thoát của chương trình, sử dụng -1 và để thư viện cắt xén nó một cách thuận tiện.

Điều đó hữu ích vì khi tập lệnh hoặc chương trình có nhiều trạng thái thoát có thể (xem grepví dụ đơn giản), các tập lệnh có ý nghĩa thường được gán cho các số nhỏ nhất, làm cho mã thoát lớn nhất có thể trở thành một lỗi tốt để sử dụng cho "lỗi không xác định" hoặc " hủy bỏ "vì không thể bao giờ xung đột với một giá trị trạng thái có ý nghĩa.


Lấy glibc làm ví dụ, trong đó thực hiện exit()như status &= 0xff. Có "cỡ chữ" trong đó -1 & 0xffkhông phải là 255 không? Tất nhiên là không, bởi vì toàn bộ mục đích là làm cho nó phù hợp trong phạm vi 0-255. Bất kể, câu cuối cùng của bạn không có ý nghĩa: mã trạng thái 128-255 có mục đích đặc biệt trong các hệ thống UNIX.
dùng222973

2
Đừng nhầm lẫn các giá trị thoát Bash (là 0-127, 128+ là các giá trị Bash đặc biệt) với các giá trị thoát chương trình (là 0-255, xem pubs.opengroup.org/onlinepub/009695399/fifts/exit.html ). Về kích thước, hãy nhớ rằng các lập trình viên C đã xử lý nhiều kích thước từ (ban đầu là 12, 16 và 32 bit) kể từ đầu để chúng tôi tự động thử các thành ngữ không yêu cầu chúng tôi xem xét kích thước từ. Do Unix có trước Posix sau 2 thập kỷ nên không có giới hạn 8 bit nên chúng tôi đã viết nên không thành vấn đề.
Todd Knarr
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.