У меня есть следующий код C ++:
template <int isBigEndian, typename val>
struct EndiannessConv
{
inline static val fromLittleEndianToHost( val v )
{
union
{
val outVal __attribute__ ((used));
uint8_t bytes[ sizeof( val ) ] __attribute__ ((used));
} ;
outVal = v;
std::reverse( &bytes[0], &bytes[ sizeof(val) ] );
return outVal;
}
inline static void convertArray( val v[], uint32_t size )
{
// TODO : find a way to map the array for (uint32_t i = 0; i < size; i++)
for (uint32_t i = 0; i < size; i++)
v[i] = fromLittleEndianToHost( v[i] );
}
};
Какая работа и была проверена (без используемых атрибутов). При компиляции я получаю следующие ошибки от g ++ (версия 4.4.1)
|| g++ -Wall -Wextra -O3 -o t t.cc
|| t.cc: In static member function 'static val EndiannessConv<isBigEndian, val>::fromLittleEndianToHost(val)':
t.cc|98| warning: 'used' attribute ignored
t.cc|99| warning: 'used' attribute ignored
|| t.cc: In static member function 'static val EndiannessConv<isBigEndian, val>::fromLittleEndianToHost(val) [with int isBigEndian = 1, val = double]':
t.cc|148| instantiated from here
t.cc|100| warning: unused variable 'outVal'
t.cc|100| warning: unused variable 'bytes'
Я пытался использовать следующий код:
template <int size, typename valType>
struct EndianInverser { /* should not compile */ };
template <typename valType>
struct EndianInverser<4, valType>
{
static inline valType reverseEndianness( const valType &val )
{
uint32_t castedVal =
*reinterpret_cast<const uint32_t*>( &val );
castedVal = (castedVal & 0x000000FF << (3 * 8))
| (castedVal & 0x0000FF00 << (1 * 8))
| (castedVal & 0x00FF0000 >> (1 * 8))
| (castedVal & 0xFF000000 >> (3 * 8));
return *reinterpret_cast<valType*>( &castedVal );
}
};
но он прерывается при включении оптимизации из-за типа punning.
Итак, почему мой атрибут used
был проигнорирован?
Есть ли обходной путь для преобразования порядка байтов (я полагаюсь на enum, чтобы избежать наложения типов) в шаблонах?