2014-02-03 8 views
3

У меня есть функция, которая выглядит следующим образом:Использует 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*. Правильно ли я предполагаю, что это было незаконно?

+0

Действительно ли 'временный_баффер'' 'неподписанный int'? И действительно ли вы копируете 'sizeof (T)' байты из этого 'unsigned int's address? Существуют ли какие-либо гарантии относительно 'sizeof (T) <= sizeof (unsigned int)'? – Angew

+0

Да, это действительно так. В начале функции есть статическое утверждение, которое обеспечивает 'sizeof (T) <= sizeof (unsigned int)'. –

+0

Упс, пропустил утверждение полностью. – Angew

ответ

2

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

В основном, это будет работать только если эти условия:

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

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

Если они выполнены, все в порядке. Это то, что на самом деле означает тривиальное копирование - он может быть скопирован байт для байта. Я бы просто использовал unsigned char вместо char, чтобы подчеркнуть, что это байты, а не символы.

+0

Все эти условия сохраняются (и применяются в фактическом коде). Вот как это выглядит при написании оберток для уродливого C apis. –