Код: Выделить всё
/**
* @brief A misaligned load can be - trying to fetch eight consecutive bytes from an address
* that is not divisible by eight. On x86 enabled by default. On ARM it's not.
*
* Most platforms support it, but there is no industry standard way to check for those.
* This value will mostly affect the performance of the serial (SWAR) backend.
*/
#ifndef SZ_USE_MISALIGNED_LOADS
#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86)
#define SZ_USE_MISALIGNED_LOADS (1) // true or false
#else
#define SZ_USE_MISALIGNED_LOADS (0) // true or false
#endif
#endif
Код: Выделить всё
void init(string_view other) noexcept(false)
{
// "other" is the string_view I passed in the constructor
sz_ptr_t start; // after allocating memory start = 0x7bfff5900029
if (!_with_alloc(
[&](sz_alloc_type &alloc) { return (start = sz_string_init_length(&string_, other.size(), &alloc)); }))
throw std::bad_alloc();
sz_copy(start, (sz_cptr_t)other.data(), other.size());
}
Код: Выделить всё
SZ_PUBLIC void sz_copy_serial(sz_ptr_t target, sz_cptr_t source, sz_size_t length) {
// The most typical implementation of `memcpy` suffers from Undefined Behavior:
//
// for (char const *end = source + length; source < end; source++) *target++ = *source;
//
// As NULL pointer arithmetic is undefined for calls like `memcpy(NULL, NULL, 0)`.
// That's mitigated in C2y with the N3322 proposal, but our solution uses a design, that has no such issues.
// https://developers.redhat.com/articles/2024/12/11/making-memcpynull-null-0-well-defined
#if SZ_USE_MISALIGNED_LOADS
while (length >= 8) *(sz_u64_t *)target = *(sz_u64_t const *)source, target += 8, source += 8, length -= 8;
#endif
while (length--) *(target++) = *(source++);
}
Код: Выделить всё
(*(sz_u64_t *)target = *(sz_u64_t const *)source
Код: Выделить всё
runtime error: store to misaligned address 0x7bfff5900029 for type 'sz_u64_t' (aka 'unsigned long'), which requires 8 byte alignment
- Если x86_64 поддерживает невыровненное чтение, и эта функция включена по умолчанию, почему UBSAN говорит, что это неопределенное поведение. Должен ли я отключить его вручную? Если я отключу его, копии в конечном итоге будут выполняться побайтно в цикле.
- Почему выделение строки для хранения происходит даже по адресу 0x7bfff5900029? Это звучит как нелепый адрес с точки зрения выравнивания, полученный от функции распределения. Обычно они выравниваются по 8 или 16 байтам.
- Эта пользовательская функция реализована потому, что memcpy(NULL) — это UB? Не лучше ли просто проверить NULL и использовать memcpy, который гарантированно будет намного лучше, чем любой ручной цикл?
Подробнее здесь: https://stackoverflow.com/questions/798 ... -sanitizer
Мобильная версия