2009-09-04 49 views
7

Có cách nào để tìm bù đắp của thành viên của cấu trúc tại thời gian biên dịch không? Tôi muốn tạo ra một hằng số chứa offset của một thành viên cấu trúc. Trong đoạn mã sau, macro offsetof() hoạt động trong câu lệnh printf đầu tiên. Tuy nhiên, việc sử dụng trong dòng 10 để khai báo sẽ tạo ra lỗi:offsetof tại thời gian biên dịch

"Cannot resolve '->' operator as a constant expression".

Còn cách nào khác để thực hiện?

struct MyStruct 
{ 
    unsigned long lw; 
    unsigned char c[5]; 
    int i; 
    int j; 
    unsigned long last; 
}; 

const int ofs = offsetof(struct MyStruct, i); // This line in error 

int main(void) 
{ 
    printf("Offset of c = %d.\n", offsetof(struct MyStruct, c)); 
    printf("Offset of i = %d.\n", ofs); 
    return 0; 
} 

Trả lời

4

Nó biên dịch mà không cảnh báo ở đây với g ++ 4, sau khi tôi thêm #includes thích hợp.

Bạn có #including stddef.h không? offsetof() là macro, không phải từ khóa được tích hợp trong C.

Nếu điều đó không khắc phục được, hãy thử tạo tĩnh liên tục, để giới hạn mô-đun đó. Điều đó có thể làm cho trình biên dịch hài lòng.

9

Macro offsetof() cấu trúc biên dịch. Không có cách nào phù hợp với tiêu chuẩn để xác định nó, nhưng mọi trình biên dịch phải có một số cách để thực hiện nó.

Một ví dụ sẽ là:

#define offsetof(type, member) ((size_t) &(((type *) 0)->member)) 

Trong khi không phải là một thời gian biên dịch xây dựng kỹ thuật (xem ý kiến ​​của người sử dụng "litb"), mỗi trình biên dịch phải có ít nhất một biểu hiện như vậy mà nó có thể giải quyết tại thời gian biên dịch, chính xác là những gì offsetof() được định nghĩa là trong <stddef.h>.

Có thể có một số lỗi khác đối với mã của bạn - bao gồm thiếu <stddef.h> hoặc một số thứ khác làm kích thích trình biên dịch của bạn.

+0

Đó không phải là ý của anh ấy với "thời gian biên dịch", tất nhiên. Bạn hiển thị một cấu trúc không sử dụng hàm thư viện, nhưng điều đó không có nghĩa là nó đánh giá thành một giá trị thời gian biên dịch. Có hay không mã thực sự được phát ra không liên quan gì - bản nháp C nói "Biểu thức hằng số số học phải có kiểu số học và chỉ có toán hạng là hằng số nguyên, hằng số, hằng số liệt kê, hằng số ký tự và biểu thức sizeof.". Con trỏ không được phép trong hỗn hợp. –

+0

'offsetof' là một thời gian biên dịch và đánh giá thành một biểu thức hằng số nguyên, nhưng việc triển khai ví dụ của bạn thì không. –

+0

Có cách * NO * trong ngôn ngữ để định nghĩa offsetof() như một cái gì đó đánh giá thành một biểu thức hằng số nguyên. Có * NO * cách để xác định nó mà không cần sử dụng con trỏ. Bất kể bạn làm gì, bạn sẽ luôn dựa vào trình biên dịch của trình biên dịch và/hoặc khả năng của trình biên dịch để tối ưu hóa biểu thức của bạn một cách thích hợp. Kiểm tra Wikipedia trên offsetof, hoặc bất kỳ thư viện C mã nguồn mở nào. Vì vậy, trong khi bạn về mặt kỹ thuật chính xác về định nghĩa của các biểu thức hằng số nguyên (và tôi thích ứng từ ngữ của tôi), bạn đã sai khi chỉ một ngón tay vào việc thực hiện ví dụ của tôi. – DevSolar

3

Nếu bạn có #include <stddef.h> như tôi giả định (thông báo lỗi bạn trích dẫn mà không có sẽ vô nghĩa), đó là lỗi trong trình biên dịch của bạn. Kết quả offsetof là một biểu thức hằng số nguyên trong C99 cũng như trong C90.

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