我最近找到了这个页面:
Making PyObject_HEAD conform to standard C
我对这段话感到好奇:
标准C对其精确设计的别名规则有一个特定的例外,以支持Python的情况:也可以通过指向第一个字段的指针访问结构类型的值。例如。 如果struct以int开头,struct *也可以强制转换为int *,允许将int值写入第一个字段。
所以我编写了这段代码来检查我的编译器:
struct with_int {
int a;
char b;
};
int main(void)
{
struct with_int *i = malloc(sizeof(struct with_int));
i->a = 5;
((int *)&i)->a = 8;
}
但我得到了error: request for member 'a' in something not a struct or union
。
我上面的段落是否合适?如果不是,我做错了什么? 另外,如果有人知道C标准在哪里引用此规则,请在此处指出。感谢。
答案 0 :(得分:5)
您的解释 1 是正确的,但代码不是。
指针i
已指向对象,因此指向第一个元素,因此您只需将其强制转换为正确的类型:
int* n = ( int* )i;
然后你只需取消引用它:
*n = 345;
或者一步到位:
*( int* )i = 345;
1 (引用自:ISO:IEC 9899:201X 6.7.2.1结构和联合说明符15)
在结构对象内,非位字段成员和位域中的单位
驻留的地址按声明的顺序增加。指向a的指针
结构对象,适当转换,指向其初始成员(或者如果该成员是a
位字段,然后到它所在的单元,反之亦然。可能有未命名的
在结构对象中填充,但不在其开头。
答案 1 :(得分:1)
你有一些问题,但这对我有用:
#include <malloc.h>
#include <stdio.h>
struct with_int {
int a;
char b;
};
int main(void)
{
struct with_int *i = (struct with_int *)malloc(sizeof(struct with_int));
i->a = 5;
*(int *)i = 8;
printf("%d\n", i->a);
}
输出是: 8
答案 2 :(得分:0)
就像其他答案指出的那样,我认为您的意思是:
// Interpret (struct with_int *) as (int *), then
// dereference it to assign the value 8.
*((int *) i) = 8;
而不是:
((int *) &i)->a = 8;
但是,没有一个答案能具体说明为什么该错误有意义。
让我解释一下((int *) &i)->a
的含义:
i
是一个变量,它保存一个(struct with_int)
的地址。 &i
是main()函数的堆栈空间上的地址。这意味着&i
是一个地址,其中包含(struct with_int)
的地址。换句话说,&i
是指向(struct with_int)
的指针。然后,强制转换(int *)
会告诉编译器将此堆栈地址解释为int
指针,即int
的地址。最后,使用该->a
,您要求编译器从此a
指针中获取结构成员int
,然后为其分配值8。从int
指针中获取结构成员是没有意义的。因此,您得到error: request for member 'a' in something not a struct or union
。
希望这会有所帮助。