问题描述
我见过一个问题 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]
只是像往常一样进行数组索引。