Bạn cũng có thể xem xét việc sử dụng này memmove
được thấy trong Git 2.14.x (Q3 2017)
Xem cam kết 168e635 (16 tháng 7 năm 2017) và cam kết 1773664 , cam kết f331ab9 , cam kết 5783980 (15 tháng 7 năm 2017) bởi René Scharfe ( rscharfe
) .
(Hợp nhất bởi Junio C Hamano - gitster
- trong cam kết 32f9025 , ngày 11 tháng 8 năm 2017)
Nó sử dụng macro trợ giúpMOVE_ARRAY
tính toán kích thước dựa trên số phần tử được chỉ định cho chúng tôi và hỗ trợ NULL
con trỏ khi số đó bằng 0.
Các memmove(3)
cuộc gọi thô với NULL
có thể khiến trình biên dịch (quá háo hức) tối ưu hóa NULL
việc kiểm tra sau này .
MOVE_ARRAY
thêm một trình trợ giúp an toàn và thuận tiện để di chuyển các phạm vi mục nhập mảng có khả năng chồng chéo.
Nó suy ra kích thước phần tử, nhân lên một cách tự động và an toàn để lấy kích thước theo byte, thực hiện kiểm tra an toàn kiểu cơ bản bằng cách so sánh kích thước phần tử và không giống như memmove(3)
nó hỗ trợ NULL
con trỏ iff 0 phần tử sẽ được di chuyển.
#define MOVE_ARRAY(dst, src, n) move_array((dst), (src), (n), sizeof(*(dst)) + \
BUILD_ASSERT_OR_ZERO(sizeof(*(dst)) == sizeof(*(src))))
static inline void move_array(void *dst, const void *src, size_t n, size_t size)
{
if (n)
memmove(dst, src, st_mult(size, n));
}
Ví dụ :
- memmove(dst, src, (n) * sizeof(*dst));
+ MOVE_ARRAY(dst, src, n);
Nó sử dụng macroBUILD_ASSERT_OR_ZERO
xác nhận phụ thuộc thời gian xây dựng, như một biểu thức (với @cond
là điều kiện thời gian biên dịch phải đúng).
Quá trình biên dịch sẽ không thành công nếu điều kiện không đúng hoặc trình biên dịch không thể đánh giá.
#define BUILD_ASSERT_OR_ZERO(cond) \
(sizeof(char [1 - 2*!(cond)]) - 1)
Thí dụ:
#define foo_to_char(foo) \
((char *)(foo) \
+ BUILD_ASSERT_OR_ZERO(offsetof(struct foo, string) == 0))