sky*_*ing 10 c pointers offsetof language-lawyer
假设我有一个结构并将偏移量提取给成员:
struct A {
int x;
};
size_t xoff = offsetof(A, x);
Run Code Online (Sandbox Code Playgroud)
如果指针以struct A标准符合方式提取成员,我该怎么办?当然假设我们有struct A*正确的偏移量.一种尝试是做类似的事情:
int getint(struct A* base, size_t off) {
return *(int*)((char*)base + off);
}
Run Code Online (Sandbox Code Playgroud)
这可能会工作,但要注意的例子指针算术只有似乎标准中定义,如果指针是相同的阵列(或一个过去的结束)的指针,这不一定是这种情况.从技术上讲,构造似乎依赖于未定义的行为.
另一种方法是
int getint(struct A* base, size_t off) {
return *(int*)((uintptr_t)base + off);
}
Run Code Online (Sandbox Code Playgroud)
这也可能会起作用,但请注意,intptr_t不需要存在,据我所知,算术intptr_t不需要产生正确的结果(例如我记得有些CPU有能力处理非字节对齐的地址,这会建议在数组中intptr_t每个步骤增加8 char.
看起来标准中有遗忘的东西(或者我错过的东西).
根据C 标准,7.19 通用定义<stddef.h>第 3 段offsetof()定义为:
\n\n\n宏是
\n\nRun Code Online (Sandbox Code Playgroud)\n\nNULL\n它扩展为实现定义的空指针常量;和
\n\nRun Code Online (Sandbox Code Playgroud)\n\noffsetof(*type*, *member-designator*)\n它扩展为具有 type\n 的整型常量表达式
\nsize_t,其值是以字节为单位的偏移量,从其结构的开头(由type指定)到\n 结构成员(由member-designator指定) 。
因此,offsetoff()返回以字节为单位的偏移量。
6.2.6.1总则第 4 段规定:
\n\n\n\n\n存储在任何其他对象类型的非位字段对象中的值由\n n \xc3\x97 CHAR_BIT位组成,其中n是该类型对象的大小(以字节为单位)。
\n
由于CHAR_BIT被定义为 a 中的位数char,因此 achar是一个字节。
因此,根据标准,这是正确的:
\n\nint getint(struct A* base, size_t off) {\n return *(int*)((char*)base + off); \n}\nRun Code Online (Sandbox Code Playgroud)\n\n它转换base为 a并向地址char *添加字节。off如果off是 的结果,则结果地址是所指向offsetof(A, x);的地址。xstructure Abase
你的第二个例子:
\n\nint getint(struct A* base, size_t off) {\n return *(int*)((intptr_t)base + off);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n取决于有符号intptr_t值与无符号size_t值相加的结果。
| 归档时间: |
|
| 查看次数: |
253 次 |
| 最近记录: |