Giả sử thư viện C phải chia sẻ chi tiết về cấu trúc với mã ứng dụng và phải duy trì tính tương thích ngược của API và ABI. Nó cố gắng làm điều này bằng cách kiểm tra kích thước của cấu trúc truyền cho nó.Làm thế nào để sizeof (struct) giúp cung cấp khả năng tương thích ABI?
Giả sử, cần phải cập nhật cấu trúc sau. Trong phiên bản thư viện 1,
typedef struct {
int size;
char* x;
int y;
} foo;
trong phiên bản 2 của thư viện, nó được cập nhật đến:
typedef struct {
int size;
char* x;
int y;
int z;
} foo_2;
Bây giờ, thư viện phiên bản 2 muốn kiểm tra nếu ứng dụng được đi qua các mới foo_2
hoặc cũ foo
làm đối số, arg
, với một hàm. Nó giả định rằng các ứng dụng đã cài đặt arg.size
-sizeof(foo)
hoặc sizeof(foo_2)
và cố gắng tìm hiểu xem mã ứng dụng groks phiên bản 2.
if(arg.size == sizeof(foo_2)) {
// The application groks version 2 of the library. So, arg.z is valid.
} else {
// The application uses of version 1 of the library. arg.z is not valid.
}
Tôi đang tự hỏi tại sao điều này sẽ không thất bại. Trên GCC 4.6.3, với cờ -O3, cả hai sizeof(foo)
và sizeof(foo_2)
là 24. Vì vậy, mã thư viện v2 sẽ không hiểu nếu ứng dụng đang chuyển cấu trúc loại foo
hoặc foo_2
? Nếu có, cách tiếp cận này dường như đã được sử dụng như thế nào?
http://blogs.msdn.com/b/oldnewthing/archive/2003/12/12/56061.aspx
theo về câu hỏi: Có một lý do chính đáng để ủng hộ việc sử dụng sizeof(struct)
cho phiên bản phân biệt đối xử? Như đã chỉ ra trong các nhận xét, tại sao không sử dụng thành viên version
rõ ràng trong cấu trúc được chia sẻ?
Bạn nhận được 24 từ đâu? –
Điều này có thể không hoạt động. 'sizeof' là một điều biên dịch, và bạn muốn kiểm tra kích thước tại * runtime *. –
@BasileStarynkevitch: Hm, cái gì? Chúng tôi wat để biết phiên bản của cấu trúc người gọi được sử dụng, không phải là callee, do đó, nó có vẻ tốt từ hướng đó. Tuy nhiên, điều này là đúng trên hầu hết các nền tảng 64 bit, con trỏ là 8 byte liên kết và có kích thước, int 4, và do đó không có sự khác biệt về kích thước giữa hai cấu trúc. – Deduplicator