c++ - 字节顺序转换和 g++ 警告

标签 c++ coding-style g++ endianness

我有以下 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 );
    }
};

但由于类型双关,启用优化时它会中断。

那么,为什么我的 used 属性被忽略了? 是否有一种解决方法可以在模板中转换字节序(我依靠枚举来避免类型双关)?

最佳答案

我只有 gcc 4.2.1,但如果我去掉 attribute((已使用))并为 union 命名,它会在没有警告的情况下编译。

  inline static val fromLittleEndianToHost( val v )
  {
        union
        {
          val   outVal ;
          uint8_t bytes[ sizeof( val ) ] ;
        } u;

        u.outVal = v;
        std::reverse( &u.bytes[0], &u.bytes[ sizeof(val) ] );

        return u.outVal;
  }

据我所读,“union ”技术适用于 gcc,但在标准中没有保证,其他“reinterpret_cast”方法是错误的(因为类型别名)。但是我认为这适用于 C,不确定 C++。希望对您有所帮助。

关于c++ - 字节顺序转换和 g++ 警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2667225/

相关文章:

mysql - 编写包含多个 OR 的 SQL 查询的更好方法

c++ - 使用成员作为参数调用构造函数解析为变量定义

c++ - 为什么 map 插入会更改对象成员值?

c++ - 类中的唯一指针

c++ - 使用 Qt 获取一些具有 KEY 字符的 ascii 值

c++ - 如何使用Enterprise Architect(EA)生成QT项目的类图?

java - 如何检查 Java 类成员顺序

java - 在函数中使用 for-each 循环更好,还是 while 循环和 “found” 变量更好?

gcc - 由于不受支持的 gcc 编译器版本,Caffe 编译失败

c++ - 不同线程中的多个 atexit 处理程序