У меня есть функция, которая выглядит так:
template<typename T>
void some_function(T* buffer) {
BOOST_STATIC_ASSERT(sizeof(T) <= sizeof(unsigned int));
unsigned int temporary_buffer;
int result = some_c_api(&temporary_buffer);
if(result == error)
throw some_exception();
// originally *buffer = reinterpret_cast<T&>(temporary_buffer), but this breaks
// strict aliasing
std::copy( reinterpret_cast<char*>(&temporary_buffer),
reinterpret_cast<char*>(&temporary_buffer) + sizeof(T),
reinterpret_cast<char*>(buffer));
}
Безопасно ли применять оба несвязанных буфера к char*
здесь и скопировать количество байтов, которое может содержать целевой буфер? Я использую не-C ++ 11 компилятор (gcc 4.1.2).
Я столкнулся с этим во время рефакторинга некоторого кода. Исходный код не имел этого предупреждения, потому что он проходил через буферы как void*
, Правильно ли я считаю, что это незаконно?
Этот кусок кода выглядит как катастрофа, ожидающая случиться. Если он должен существовать по какой-либо причине, он должен быть заполнен статическими утверждениями и комментариями, чтобы прояснить намерение.
По сути, это будет работать только в том случае, если выполняются следующие условия:
sizeof(T) <= sizeof(unsigned int)
(потому что вы копируете из unsigned int
в T
). Я вижу, это уже утверждено, хорошо.
T
легко копируется (в соответствии с C ++ 11 std::is_trivially_copyable
черта характера). Если ваш компилятор не поддерживает Boost-эквивалент этой черты, просто запишите это требование.
Пока они встречаются, это нормально. Вот что на самом деле означает простое копирование — его можно копировать байт за байт. Я бы просто использовал unsigned char
вместо char
подчеркнуть тот факт, что это байты, а не символы.
Других решений пока нет …