简体   繁体   English

使用 (unsigned int *) 和 (unsigned int **) 进行的 void 指针类型转换

[英]void pointer type cast with (unsigned int *) and (unsigned int **)

unsigned int num = 101;

void * p = #

void ** pp = &p;

unsigned int *get_data_1 = NULL;
unsigned int *get_data_2 = NULL;

get_data_1 = *((unsigned int *)pp);

get_data_2 = *((unsigned int **)pp);

Here get_data_1 and get_data_2 what will be the difference?这里get_data_1get_data_2会有什么区别呢?

I have type casted with (unsigned int *) and (unsigned int **).我使用 (unsigned int *) 和 (unsigned int **) 进行类型转换。

Both operations invoke Undefined Behavior .这两个操作都会调用Undefined Behavior The value of type void* pointed by pp is accessed via a l-value expression of incompatible type unsigned int or unsigned int* respectively. pp指向的类型void*的值分别通过不兼容类型unsigned intunsigned int*的左值表达式访问。 This violates strict aliasing rule.这违反了严格的别名规则。

As both operations are UB thus there is no defined difference between those two operations.由于这两个操作都是UB ,因此这两个操作之间没有明确的区别

The correct accessing should be by dereferencing pp first to obtain value of type void* and use implicit casting from void* to unsigned int* .正确的访问应该是首先取消引用pp以获得void*类型的值并使用从void*unsigned int*的隐式转换。 Finally dereference correctly typed pointer:最后取消引用正确类型的指针:

unsigned int *get_data_3 = *pp;
return *get_data_3;

TL;DR TL;博士

Don't do any of this, it is dangerous and incorrect C for a number of reasons.不要这样做,出于多种原因,这是危险且不正确的 C 语言。 My general advise to beginners is to never use the cast operator at all - there shouldn't be a lot of situations where you actually need to use it.我对初学者的一般建议是永远不要使用 cast 运算符 - 不应该有很多情况下您实际上需要使用它。


Generally, C allows wild and dangerous pointer conversions between object pointers that are not compatible, as long as there are no alignment concerns regarding the type pointed-at.通常,只要不存在与指向的类型有关的对齐问题,C 允许在不兼容的对象指针之间进行狂野和危险的指针转换。 (6.3.2.3/7) (6.3.2.3/7)

However, should you first cast to a non-compatible type and then de-reference the pointer, all manner of undefined behavior might kick in. 6.7.6.1:但是,如果您首先转换为不兼容的类型,然后取消引用指针,则可能会出现各种未定义的行为。6.7.6.1:

For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types.对于要兼容的两种指针类型,两者都应具有相同的限定,并且都应是指向兼容类型的指针。

Also there are the whole "strict aliasing" concerns regarding "lvalue access" (6.5).还有关于“左值访问”(6.5)的整个“严格别名”问题。

Specifically:具体来说:

  • (unsigned int *)pp the pointer conversion is probably ok given that pp points at an aligned address. (unsigned int *)pp指针转换可能没问题,因为pp指向对齐的地址。
  • *((unsigned int *)pp) invokes undefined behavior since a lvalue of type void* is accessed as an unsigned int and they are not compatible types. *((unsigned int *)pp)调用未定义的行为,因为void*类型的左值作为unsigned int访问,并且它们不是兼容的类型。
  • unsigned int *get_data_1 = <unsigned int lvalue> is a constraint violation - invalid C. As per 6.5.16.1. unsigned int *get_data_1 = <unsigned int lvalue>是违反约束的 - 无效 C。根据 6.5.16.1。 C has never allowed an integer to get assigned to a pointer and vise versa, explicit casts are required. C 从未允许将整数分配给指针,反之亦然,需要显式转换。
  • (unsigned int **)pp similarly the pointer conversion in itself is "probably ok". (unsigned int **)pp同样,指针转换本身“可能还可以”。 But again unsigned int** is not compatible with void** .但同样unsigned int**void**不兼容。 Notably, the special generic rules regarding void* conversions do not apply to void** .值得注意的是,关于void*转换的特殊通用规则不适用于void**
  • *((unsigned int **)pp) accesses a void* as a unsigned int* . *((unsigned int **)pp)void*作为unsigned int*访问。 Again this is a strict aliasing violation, because although we may convert to/from void* to any object pointer, they need not have the same internal presentation (though in practice it's very likely).这又是一个严格的别名违规,因为尽管我们可以将 void* 转换为/从void*转换为任何对象指针,但它们不需要具有相同的内部表示(尽管在实践中很有可能)。 They are not compatible types as per the quoted 6.7.6.1.根据引用的 6.7.6.1,它们不是兼容的类型。
  • unsigned int *get_data_2 = <unsigned int* lvalue> is ok. unsigned int *get_data_2 = <unsigned int* lvalue>没问题。

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

相关问题 如何将 unsigned int 转换为指针并取消引用它? - How to cast a unsigned int to a pointer and dereference it? 在有符号的int和无符号的int之间进行转换时是否需要强制类型转换? - Is a type cast necessary while converting between signed int and unsigned int? C: int 或 unsigned int 哪种类型我用于指针增加 - C: int or unsigned int which type I used for pointer increasement 将unsigned int的指针传递给long int的指针 - Passing pointer of unsigned int to pointer of long int 当我将指向unsigned int的指针转换为unsigned long long指针时,为什么会看到更大的值? - Why do I see a bigger value when I cast pointer to unsigned int as unsigned long long pointer? 强制转换为int,无符号int用于c中的指针 - cast of int,unsigned int for pointers in c 如何在 C 中将无符号 int 转换或转换为 int? - How to cast or convert an unsigned int to int in C? 是否可以使用 fscanf 读取字符串并将其保存为 unsigned int 在 unsigned int 指针中? - Is it possible to read a string with fscanf and save it as unsigned int in an unsigned int pointer? 在 C 中将 char_array 类型转换为 unsigned int - Type Cast char_array to unsigned int in C 是否将“ unsigned int”视为数据类型? - Is “unsigned int” considered to be a data type?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM