(int*) &var 和 reinterpret_cast 一样吗?

问题描述

我见过一个问题 What does (int*) &var mean? 有这样的代码

  char i;
  int* p = (int*) &i;

当我试图从here这部分理解

#define     vertexmark(vx)   ((int *) (vx))[m->vertexmarkindex] 
#define     setvertexmark(vx,value)   ((int *) (vx))[m->vertexmarkindex] = value

看起来很相似,但第二段代码仍然让我感到困惑。有人可以解释一下这是怎么回事吗?

我对现代 C++11 也很好奇,这种 C 风格的类型转换应该用 reinterpret_cast 替换吗?

解决方法

(int*) &var 和 reinterpret_cast 一样吗?

这取决于 var 的类型。对于某些类型,它是相同的,而对于其他类型则不是。在示例案例中,它是相同的。

这是一个不一样的例子:

const char i{};
int* p1 = (int*) &i;                  // well-formed (but dangerous)
int* p2 = reinterpret_cast<int*>(&i); // ill-formed

我对现代 C++11 也很好奇,这种 C 风格的类型转换应该用 reinterpret_cast 替换吗?

是的,这与现代性或 C++11 无关。即使您使用的是 C++98,您也应该避免使用 C 风格的强制转换。您还应该避免使用类似的宏,而应使用函数。

,

这些是旧式的 C 类型转换,您的 linter 规则可能会促使您将它们转换为 reinterpret_cast 或 static_cast。

在你用英文写的代码中,“获取 i 的地址”,它是一个指向 char 的指针,“但把它当作一个指向 int 的指针”。它可以防止编译器抱怨。 “我知道这是错误的,但我是故意这样做的。”

在您列出的 #defines 中,我们不知道 vx 到底是什么类型。也许它被作为 void * 或其他东西传递。但他们基本上假设它是一个 int 数组,并从中获取 m->vertexmarkindex 元素。

第二个是二传手。

坦率地说,这让我觉得设计很糟糕,但如果不深入研究,我们不确定。我认为它来自一个非常古老的 C 库。

,

看起来很相似,但第二段代码仍然让我感到困惑。有人可以解释一下这是怎么回事吗?

让我们稍微解构一下:

((int *) (vx))[m->vertexmarkindex] = value

(vx):宏的参数被包裹在一组括号中。这是为了允许宏与复合表达式一起使用。没有它,setvertexmark(ptr + 3,0); 会变成 ((int *)ptr + 3)[m->vertexmarkindex] = 0;,这会导致错误的偏移量。

从那时起,((int *) ptr) 只是将缓冲区重新解释为整数数组,而 [m->vertexmarkindex] 只是像往常一样进行数组索引。