2010-04-02 32 views
5

Linux stddef.h định nghĩa offsetof() như:Tại sao trừ con trỏ null trong offsetof()?

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 

trong khi các bài viết Wikipedia trên offsetof() (http://en.wikipedia.org/wiki/Offsetof) định nghĩa nó như:

#define offsetof(st, m) \ 
    ((size_t) ((char *)&((st *)(0))->m - (char *)0)) 

Tại sao trừ (char *)0 trong phiên bản Wikipedia? Có trường hợp nào thực sự tạo nên sự khác biệt không?

+0

Bạn không nên sử dụng/nghiên cứu mã có thể gọi hành vi không xác định, như ở trên. Việc triển khai có thể sử dụng các hacks skanky như vậy vì họ biết những hành vi không xác định nào hoạt động bí mật. Nhưng những gì "bí mật hoạt động" là hoàn toàn không di động. – CTMacUser

Trả lời

6

Phiên bản đầu tiên chuyển đổi một con trỏ vào một số nguyên với một dàn diễn viên, mà không phải là cầm tay.

Phiên bản thứ hai dễ di chuyển hơn trên nhiều trình biên dịch khác nhau, bởi vì nó dựa vào số học con trỏ của trình biên dịch để lấy kết quả số nguyên thay vì kiểu chữ.

BTW, tôi là người biên tập đã thêm mã gốc vào mục nhập Wiki, đây là dạng Linux. Sau đó, các biên tập viên đã thay đổi nó thành phiên bản di động hơn.

+0

Cảm ơn bạn đã phản hồi. Câu hỏi tiếp theo "Có (size_t) ((char *) 0) không bao giờ được đánh giá là 0?" được đăng tại http://stackoverflow.com/questions/2581522/does-size-tchar-0-ever-not-evaluate-to-0 –

+0

Thú vị - nhưng là biểu thức thứ hai thực sự di động hơn, vì số học con trỏ trên con trỏ null không định nghĩa được? –

+1

Tính di động cao hơn theo nghĩa là nó hoạt động trên nhiều CPU hơn. Không được xác định (theo tiêu chuẩn) không có nghĩa là nó không thể làm việc cho một số kiến ​​trúc cụ thể. –

4

Tiêu chuẩn không yêu cầu con trỏ NULL để đánh giá mẫu bit 0 nhưng có thể đánh giá theo giá trị nền tảng cụ thể.

Làm phép trừ đảm bảo rằng khi chuyển đổi thành một giá trị số nguyên, NULL là 0.

+2

Đó không phải là lý do; bất kỳ hằng số hợp lý nào khác ngoài '0' cũng có thể được sử dụng. Xem câu trả lời của tôi dưới đây. –

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