Безопасно ли использовать std :: copy для обхода строгих алиасов?

У меня есть функция, которая выглядит так:

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*, Правильно ли я считаю, что это незаконно?

3

Решение

Этот кусок кода выглядит как катастрофа, ожидающая случиться. Если он должен существовать по какой-либо причине, он должен быть заполнен статическими утверждениями и комментариями, чтобы прояснить намерение.

По сути, это будет работать только в том случае, если выполняются следующие условия:

  • sizeof(T) <= sizeof(unsigned int) (потому что вы копируете из unsigned int в T). Я вижу, это уже утверждено, хорошо.

  • T легко копируется (в соответствии с C ++ 11 std::is_trivially_copyable черта характера). Если ваш компилятор не поддерживает Boost-эквивалент этой черты, просто запишите это требование.

Пока они встречаются, это нормально. Вот что на самом деле означает простое копирование — его можно копировать байт за байт. Я бы просто использовал unsigned char вместо char подчеркнуть тот факт, что это байты, а не символы.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]