【发布时间】:2018-02-17 19:35:30
【问题描述】:
这个问题是关于使用带有结构偏移的指针算术派生的指针。
考虑以下程序:
#include <cstddef>
#include <iostream>
#include <new>
struct A {
float a;
double b;
int c;
};
static constexpr auto off_c = offsetof(A, c);
int main() {
A * a = new A{0.0f, 0.0, 5};
char * a_storage = reinterpret_cast<char *>(a);
int * c = reinterpret_cast<int *>(a_storage + off_c));
std::cout << *c << std::endl;
delete a;
}
这个程序似乎可以工作,并在我测试的编译器上给出了预期的结果,使用默认设置和 C++11 标准。
(一个密切相关的程序,我们使用void *而不是char *和static_cast而不是reinterpret_cast,
不被普遍接受。 gcc 5.4 发出关于 void 指针的指针运算的警告,clang 6.0 表示该指针
void * 的算术运算是错误的。)
该程序是否具有符合 C++ 标准的明确定义的行为?
答案是否取决于实现是否具有宽松的或严格的指针安全性 ([basic.stc.dynamic.safety])?
【问题讨论】:
-
这是家庭作业吗?
-
@GarrGodfrey:我会感到惊讶...
-
为什么不使用指向 C++ 成员功能的指针。它是
offsetof的“干净”替代品? -
不,我毕业了,我没有更多的家庭作业了 :) 我想我确实以家庭作业的方式提出了这个问题。有时当你问标准问题时,最好用一个特定的代码示例提出一个开放式问题,而不是开始解释你认为你知道的东西,以我有限的经验
-
不要对
void*进行指针运算。任何T*的指针运算都需要sizeof(T),但void没有大小。
标签: c++ c++11 pointers language-lawyer offsetof