Tiêu chuẩn C đảm bảo rằng đó size_t
là một loại có thể chứa bất kỳ chỉ số mảng nào. Điều này có nghĩa là, về mặt logic, size_t
sẽ có thể giữ bất kỳ loại con trỏ nào. Tôi đã đọc trên một số trang web mà tôi tìm thấy trên Google rằng đây là hợp pháp và / hoặc sẽ luôn hoạt động:
void *v = malloc(10);
size_t s = (size_t) v;
Vì vậy, trong C99, tiêu chuẩn đã giới thiệu các loại intptr_t
và uintptr_t
loại, được ký và loại không dấu được đảm bảo để có thể giữ con trỏ:
uintptr_t p = (size_t) v;
Vậy sự khác biệt giữa sử dụng size_t
và là uintptr_t
gì? Cả hai đều không dấu và cả hai sẽ có thể giữ bất kỳ loại con trỏ nào, vì vậy chúng có vẻ giống nhau về mặt chức năng. Có bất kỳ lý do thuyết phục thực sự để sử dụng uintptr_t
(hoặc tốt hơn, a void *
) chứ không phải là size_t
, ngoài sự rõ ràng? Trong một cấu trúc mờ, trong đó trường sẽ chỉ được xử lý bởi các hàm bên trong, có lý do gì để không làm điều này không?
Với cùng một mã thông báo, ptrdiff_t
đã là một loại được ký có khả năng giữ sự khác biệt của con trỏ và do đó có khả năng giữ hầu hết mọi con trỏ, vậy nó khác với intptr_t
như thế nào?
Không phải tất cả các loại này về cơ bản đều phục vụ các phiên bản khác nhau của cùng một chức năng sao? Nếu không, tại sao? Tôi không thể làm gì với một trong số họ mà tôi không thể làm với người khác? Nếu vậy, tại sao C99 lại thêm hai loại cơ bản không cần thiết vào ngôn ngữ?
Tôi sẵn sàng bỏ qua các con trỏ hàm, vì chúng không áp dụng cho vấn đề hiện tại, nhưng cứ thoải mái đề cập đến chúng, vì tôi có một nghi ngờ lén lút chúng sẽ là trung tâm của câu trả lời "chính xác".
size_t
vàuintptr_t
nhưng những gì vềptrdiff_t
vàintptr_t
- sẽ không được cả hai trong số này có thể lưu trữ cùng một phạm vi giá trị trên nền tảng hầu như bất kỳ? Tại sao có cả hai loại số nguyên có kích thước con trỏ được ký và không dấu, đặc biệt nếuptrdiff_t
đã phục vụ mục đích của loại số nguyên có kích thước con trỏ đã ký.