2012-03-25 40 views
34

Tôi đang viết mô-đun xuất giao diện tương tự sendrecv.Tôi có nên đặt errno không?

Vì các hàm đó được cho là trả về số byte gửi và nhận, tôi không thể thực hiện quản lý lỗi đúng như tôi thường làm (tức là sử dụng số đếm và trả về giá trị ghi nhớ).

Trong tình huống như vậy, tôi có nên đặt errno làm thư viện chuẩn không? Nếu vậy, vì errno là chủ đề cụ thể, có cách viết cụ thể nào trên đó hay tôi có thể chỉ định giá trị cho nó?

Chỉnh sửa: thử nghiệm nó Tôi nhận thấy rằng thiết lập errno theo bài tập đang hoạt động. Tuy nhiên: điều này có an toàn và dễ dàng cho bất kỳ hệ thống nào không?

+4

Đối với nhiều hơn bao giờ bạn muốn biết về 'errno' và tiêu chuẩn C, hãy xem http://stackoverflow.com/questions/12945486/ – Nemo

Trả lời

28

Đây là một chút cũ, nhưng errno - manual section 3 nói rằng bạn có thể trực tiếp gán cho nó, mặc dù nó là một vĩ mô, và nó sẽ được thread địa phương

+0

Không có gì hơi lạ về nó :-) Các tiêu chuẩn nói rằng nó mở rộng đến một giá trị sửa đổi. – paxdiablo

7

Thực ra, bạn có thể có thể thực hiện quản lý lỗi "thích hợp" (khi bạn đặt) do bạn trả lại int.

Chỉ cần sử dụng giá trị không âm cho số byte đọc hoặc viết và giá trị âm cho mã lỗi. Bạn không để hạn chế bản thân để -1:

enum myerrors { 
    ERR_NO_MEMORY = -1, 
    ERR_BAD_ARGS  = -2, 
    ERR_CPU_EXPLODED = -3, 
    // and so on 
}; 

Tuy nhiên, thiết lập errno trong thời trang bạn muốn là hợp lệ. Tiêu chuẩn nêu rõ rằng errno mở rộng thành giá trị có thể sửa đổi, nghĩa là bạn có thể đặt nó. Từ C1x/n1425, 7.5 Errors <errno.h>:

... và errno mà mở rộng đến một giá trị trái sửa đổi mà có kiểu int, giá trị của nó được xác lập đối với một số lỗi tích cực bởi một số chức năng của thư viện.

+0

Điểm công bằng (thực sự trong một số điểm tôi trở lại - 2) – Dacav

2

Từ: http://support.sas.com/documentation/onlinedoc/sasc/doc700/html/lr1/errno.htm

Các chỉ các giá trị di động cho errnoEDOMERANGE

Vì vậy, câu trả lời cho po của bạn câu hỏi rtability.

+0

Tôi đã quan tâm nhiều hơn đến chi tiết kỹ thuật của việc chỉ định nó, nhưng tôi đã không mong đợi loại vấn đề về tính di động này! :) – Dacav

+1

@ Dacav - Tôi không nghĩ rằng có bất kỳ cách đặc biệt nào bạn phải đặt nó ... bạn chỉ có thể gán cho nó ... Tôi sẽ sử dụng các giá trị được liệt kê đã xác định trong 'errno.h' nếu có thể. – prelic

+3

Danh sách đó không hoàn chỉnh, 'EILSEQ' được bắt buộc theo tiêu chuẩn. – paxdiablo

6

Bạn chỉ có thể gán giá trị cho errno, nhưng hãy nhớ rằng có những cách khác để báo hiệu một lỗi đó, tùy thuộc vào tình hình của bạn, có thể phù hợp hơn:

  1. Đừng trả lại số byte được đọc, nhưng thay vào đó có thông số đầu ra với loại int * (hoặc size_t * hoặc bất kỳ thứ gì bạn sử dụng). Sau đó, bạn có thể trả lại mã lỗi.
  2. Giả sử rằng loại trả về của bạn là loại đã ký và số lượng byte đã gửi hoặc nhận không hợp lý, hãy sử dụng giá trị âm để báo hiệu các điều kiện lỗi tương ứng.
+0

'errno' được sử dụng bởi gần như tất cả các hàm trong POSIX (ngoại trừ các hàm trả về mã lỗi và một vài ngoại lệ lạ), không chỉ là các công cụ cấp thấp. –

+0

Đồng ý, tôi đã xóa phần đó. –

11

Không chỉ thể bạn thiết errno, trong nhiều trường hợp, bạn nên thiết errno. Khi gọi một số chức năng thư viện, bạn chỉ có thể phát hiện lỗi một cách đáng tin cậy nếu trước tiên bạn đặt errno thành 0. See strtol for an example.

Từ đặc điểm kỹ thuật POSIX của strtol:

[CX] [Tùy chọn Start] Các strtol() chức năng sẽ không thay đổi các thiết lập của errno nếu thành công.

Vì 0, {LONG_MIN} hoặc {LLONG_MIN} và {LONG_MAX} hoặc {LLONG_MAX} được trả lại do lỗi và cũng là lợi nhuận hợp lệ khi thành công, ứng dụng muốn kiểm tra các tình huống lỗi nên đặt errno thành 0, sau đó gọi strtol() hoặc strtoll(), sau đó kiểm tra errno. [Tùy chọn kết thúc]

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