2010-10-07 27 views
9

Tôi đã bắt đầu đọc Bình luận Lions trên Unix v6. Tôi đã xem những đoạn trích này, mà tôi chưa từng thấy trong ngôn ngữ C. Tác giả cung cấp một số loại giải thích, nhưng ai đó có thể giải thích cho tôi những gì đang xảy ra ở đây?Cấu trúc ẩn danh trong C được tìm thấy trong hạt nhân Unix

params.h:

SW 0177570 
...... 
struct { int integ; }; 

và điều này được sử dụng trong unix/prf.c

if(SW->integ == 0) 

Giải thích của tác giả

SW được định nghĩa trước đây như giá trị 0177570. Đây là địa chỉ hạt nhân của một số chỉ đọc bộ xử lý đăng ký lưu trữ các thiết lập của thanh ghi chuyển đổi giao diện điều khiển. Ý nghĩa của tuyên bố là rõ ràng: có được nội dung tại vị trí 0177570 và xem liệu chúng có không. Vấn đề là để thể hiện điều này trong C. Mã số if (SW == 0) sẽ không chuyển tải ý nghĩa này. Rõ ràng SW là giá trị con trỏ phải là bị hủy đăng ký. Trình biên dịch có thể đã được thay đổi để chấp nhận if (SW-> == 0) nhưng khi nó đứng, điều này là không chính xác về cú pháp. Bằng cách phát minh ra một cấu trúc giả, với một phần tử integ, người lập trình đã tìm thấy một giải pháp thỏa đáng để vấn đề của mình.

Câu hỏi của tôi chủ yếu là cách tính năng này hoạt động? Khi trình biên dịch thấy SW->integ, cách trình biên dịch liên kết SW với cấu trúc ẩn danh?

Trả lời

6

IIRC, trình biên dịch C cổ đại lưu giữ tất cả các tên trường (chẳng hạn như integ) trong một không gian tên duy nhất thay vì tạo một không gian tên trên mỗi loại struct. Chúng cũng không phân biệt được giữa các con trỏ structint, do đó mọi con trỏ đều có trường integ tương ứng với số sizeof(int) byte đầu tiên của nó. Kể từ integ là giá trị đầu tiên trong một struct và có loại int, SW->integ tương ứng với *((int *)SW).

+2

Trong C hiện đại, chúng tôi sẽ sử dụng 'int * const SW = 0177570; 'Nhưng trước khi sự ra đời của trình tối ưu hóa, điều đó sẽ có chi phí Ken và bó của mình tốn kém hai byte :) –

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