简体   繁体   English

将 int (*a)[4] 转换为 int *p

[英]Cast int (*a)[4] to int *p

Is it legal to cast a pointer to an array of ints to an int pointer?将指向 int 数组的指针转换为 int 指针是否合法?

int arr[4];
int (*a)[4] = &arr; 
int *p = (int*)a;

C 2018 6.3.2.3 7 says we can convert an int (*)[4] to an int * : C 2018 6.3.2.3 7 说我们可以将int (*)[4]转换为int *

A pointer to an object type may be converted to a pointer to a different object type.指向对象类型的指针可以转换为指向不同对象类型的指针。 If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined…如果结果指针没有与引用类型正确对齐,则行为未定义......

The alignment is necessarily correct since an array of int must have the alignment required for an int .该对准是一定正确,因为阵列int必须有一个所需的对齐int

However, the only thing the C standard says about the value resulting from this conversion is:但是,C 标准关于此转换产生的的唯一说明是:

… when converted back again, the result shall compare equal to the original pointer. ...当再次转换回来时,结果将与原始指针相等。

This means that an int * can temporarily hold the value of an int (*)[4] .这意味着int *可以临时保存int (*)[4] If we execute:如果我们执行:

int arr[4];
int (*x)[4] = &arr;
int *y = (int *) x;
int (*z)[4] = (int (*)[4]) y;

then we know x == z is true because the standard tells us that.然后我们知道x == z是真的,因为标准告诉我们。 But we do not know what y is.但我们不知道y是什么。 Because the standard permits different types of pointers to have different representations (use the bits that represent their values in different ways), it is possible that y has no useful meaning as an int * .由于标准允许不同类型的指针具有不同的表示形式(使用以不同方式表示其值的位),因此y作为int *可能没有任何有用的含义。 The C standard does not say the converted pointer can be used to access objects. C 标准没有说转换后的指针可用于访问对象。

Most C implementations either support this deliberately or as an artifact of how they are designed.大多数 C 实现要么有意地支持这一点,要么作为它们设计方式的产物。 However, in terms of what the C standard specifies, no guarantee is given.但是,就 C 标准规定的内容而言,没有给出任何保证。

If the original pointer's initialized to either NULL or a valid pointer to an int[4] , then yes.如果原始指针初始化为NULL或指向int[4]的有效指针,则是。 Pointer casts must not violate alignment requirements lest you get UB .指针转换不能违反对齐要求,以免得到UB A cast such as what I've described won't violate such requirement ̶a̶n̶d̶ ̶f̶u̶r̶t̶h̶e̶r̶m̶o̶r̶e̶ ̶i̶t̶ ̶w̶i̶l̶l̶ ̶b̶e̶ ̶u̶s̶a̶b̶l̶e̶ ̶f̶o̶r̶ ̶d̶e̶r̶e̶f̶e̶r̶e̶n̶c̶i̶n̶g̶ ̶b̶e̶c̶a̶u̶s̶e̶ ̶i̶f̶ ̶t̶h̶e̶ ̶ ̶i̶n̶t̶(̶*̶a̶)̶[̶4̶]̶ ̶ ̶i̶s̶ ̶v̶a̶l̶i̶d̶ ̶a̶n̶d̶ ̶n̶o̶n̶n̶u̶l̶l̶ ̶t̶h̶e̶n̶ ̶t̶h̶e̶r̶e̶ ̶i̶n̶d̶e̶e̶d̶ ̶i̶s̶ ̶a̶n̶ ̶ ̶i̶n̶t̶ ̶ ̶a̶t̶ ̶ ̶(̶i̶n̶t̶*̶)̶a̶ ̶.作为高光泽如我所描述的不会违反这些要求,而且这将是可用于非关联化,因为如果̶ ̶i̶n̶t̶(̶*̶a̶)̶[̶4̶]̶ ̶是有效的,非空则存在确实是一个̶ ̶i̶n̶t̶ ̶ ̶a̶t̶ ̶ ̶(̶i̶n̶t̶*̶)̶a̶ ̶。

If you feel uneasy about pointer casts (as you should), you can effect the conversion in this case without casting by simply doing *a (will get int[4] which will decay to int* ) or a[0] or &a[0][0] or &(*a)[0] .如果您对指针转换感到不安(正如您应该的那样),您可以在这种情况下通过简单地执行*a (将得到int[4]将衰减为int* )或a[0]&a[0][0]&(*a)[0] That way, you can also dereference the result while adhering to the letter of the standard.这样,您还可以在遵守标准字母的同时取消引用结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM