2011-12-07 32 views
10

Tôi đang đọc một cuốn sách (Lập trình nâng cao trong môi trường UNIX) và tôi sẽ đi qua phần về tín hiệu.Đúc số nguyên cho hàm con trỏ trong mã tín hiệu - tại sao tính năng này hoạt động?

Khi sử dụng chức năng tín hiệu:

void (*signal(int signo, void (*func)(int)))(int); 

tham số, func, có thể là một con trỏ tới một hàm được định nghĩa bởi người sử dụng, hoặc nó có thể được SIG_ERR, SIG_DFL, hoặc SIG_IGN.

Câu hỏi của tôi không nằm trong phần UNIX, nhưng tôi muốn cung cấp thông tin cơ bản. Những gì tôi thực sự muốn biết là, cuốn sách nói rằng những hằng số được defiend như:

#define SIG_ERR (void (*)())-1 

và những thứ tương tự cho 0 và 1.

Bây giờ, tôi có một số dự đoán khá nhưng để tiết kiệm thời gian - ai đó có thể cho tôi biết những gì heck này đang làm và tại sao nó hoạt động?

Ngoài ra, có một ... erm ... sạch hơn? cách viết này giả sử tôi đang sử dụng C + + và tương tác với C API này?

Trả lời

11

Đang truyền số nguyên cho con trỏ hàm; * các giá trị giữ chỗ được cho là đã chọn để chúng không bao giờ có thể va chạm với các giá trị của các con trỏ hàm thực. Việc thực hiện signal có lẽ sau đó kiểm tra đối số đầu vào cho các giá trị đặc biệt này.


* Chuẩn C cho phép điều này (xem 6.3.2.3 p.5), mặc dù kết quả được xác định bằng thực hiện. Rõ ràng, các tác giả của hệ điều hành có thể kiểm soát các khía cạnh thực hiện được xác định này, vì vậy mọi thứ đều ổn.

+0

Ah, do đó, nó làm cho một con trỏ hàm đến một địa chỉ cố ý (nhưng được xác định). Tôi nghĩ nó trông như thế nhưng nó có vẻ sai vì một lý do nào đó. Cảm ơn bạn! –

2
#define SIG_ERR (void (*)())-1 

này phôi -1 đến một con trỏ đến một chức năng (cụ thể là một hàm mang theo gì và trả về không có gì). Điều này sẽ làm cho SIG_ERR luôn không hợp lệ và khác biệt với NULL.

2

Vâng, nó xác định SIG_ERR làm con trỏ để làm mất chức năng chấp nhận bất kỳ số đối số nào có địa chỉ là -1. SIG_DFL có địa chỉ 0 và SIG_IGN có địa chỉ 1. Đây chỉ là giá trị đặc biệt cho chức năng xử lý tín hiệu ban đầu và các địa chỉ đó có thể là chi tiết triển khai mà bạn không nên quan tâm. Chỉ cần sử dụng macro vui lòng xác định cho bạn và bạn sẽ được tốt.

Nếu bạn muốn nó sạch hơn - tuyên bố chức năng riêng của bạn, ví dụ chức năng mà không làm gì và bỏ qua tín hiệu, và sử dụng một con trỏ đến nó thay vì SIG_IGN ...

Nhưng tôi nghi ngờ bất kỳ giá trị trong gói xử lý tín hiệu trong mã C++. Đối với một số lý do C + + lập trình muốn bọc hoàn toàn tất cả mọi thứ, ngay cả điều này đơn giản và thẳng về phía trước C API.

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