c++ - reinterpret_cast 右值和优化

标签 c++ casting

我正在将一堆代码转换为使用 C++ 风格的转换(在 -Wold-style-cast 的帮助下)。我并不完全相信它对原始变量的使用,但总的来说我是 C++ 风格转换的新手。

一个问题发生在一些字节序转换代码中。当前代码如下所示:

#define REINTERPRET_VARIABLE(VAR,TYPE) (*((TYPE*)(&VAR)))

//...

uint16_t reverse(uint16_t val) { /*stuff to reverse uint16_t*/ }
 int16_t reverse( int16_t val) {
    uint16_t temp = reverse(REINTERPRET_VARIABLE(val,uint16_t));
    return REINTERPRET_VARIABLE(temp,int16_t);
}    

现在,字节顺序并不关心签名。因此,要反转 int16_t,我们可以完全将其视为 uint16_t 以达到反转的目的。这建议这样的代码:

 int16_t reverse( int16_t val) {
    return reinterpret_cast<int16_t>(reverse(reinterpret_cast<uint16_t>(val)));
}

但是,如 this 中所述特别是 this问题是,reinterpret_cast 需要引用或指针(除非它正在转换为自身)。这表明:

 int16_t reverse( int16_t val) {
    return reinterpret_cast<int16_t&>(reverse(reinterpret_cast<uint16_t&>(val)));
}

这是行不通的,因为正如我的编译器告诉我的那样,外部转换需要一个左值。要解决此问题,您需要执行以下操作:

 int16_t reverse( int16_t val) {
    uint16_t temp = reverse(reinterpret_cast<uint16_t&>(val));
    return reinterpret_cast<int16_t&>(temp);
}

这和原来的代码差别不大,临时变量的存在也是同样的道理,但是给我提了四个问题:

  1. 为什么 reinterpret_cast 甚至需要临时的?我可以理解一个愚蠢的编译器需要有一个临时的来支持 REINTERPRET_VARIABLE 的指针肮脏,但是 reinterpret_cast 应该只是重新解释位。这与 RVO 有冲突吗?
  2. 要求该临时值是否会导致性能下降,或者编译器是否有可能确定该临时值真的应该只是返回值?
  3. 第二个reinterpret_cast 看起来像是在返回一个引用。由于函数返回值不是引用,所以我很确定这没问题;返回值将是一个拷贝,而不是引用。但是,我仍然想知道转换为引用到底意味着什么?它在这种情况下是合适的,对吗?
  4. 还有其他我应该注意的性能影响吗?我猜 reinterpret_cast 会(如果有的话)更快,因为编译器不需要弄清楚这些位应该被重新解释——我只是告诉它他们应该?

最佳答案

  1. temp是必需的,因为 & (地址)运算符在下一行应用于它。此运算符需要一个左值(要获取其地址的对象)。

  2. 我希望编译器能够优化它。

  3. reinterpret_cast<T&>(x)* reinterpret_cast<T *>(&x)相同, 它是一个左值,指定与 x 相同的内存位置占据。请注意,表达式的类型永远不是引用;但转换为 T& 的结果,或使用 *运算符是一个左值。

  4. 我预计不会出现任何性能问题。

这段代码没有严格的别名问题,因为它允许将整数类型别名为相同类型的有符号或无符号变体。但是您建议代码库中充满了重新解释的转换,因此您应该注意其他地方是否存在严格的别名违规行为,也许可以使用 -fno-strict-aliasing 进行编译。直到解决为止。

关于c++ - reinterpret_cast 右值和优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25691986/

相关文章:

c# - 当结构是在 C# 中转换的泛型对象的协变类型时,结构无法转换为对象的任何解决方法?

c++ - C 预处理器在多大程度上考虑整数文字后缀?

c++ - 'malloc' 和 'new' 是如何工作的?它们有何不同(实现方面)?

c++ - 控制台中的 OutputDebugString()

c++ - 将 'std::initializer_list<int>' 转换为 'int'

java - Lambdaj 类类型转换

c++:将指针转换为函数是否安全?

c# - 转换失败 : IList<T> to Custom Class implementing ICollection<T>

c++ - 将键盘事件透明地传递给 QProcess 的推荐方法是什么?

python-3.x - python : casting map object to list makes map object empty?