【问题标题】:Is uint8_t* equivalent to unsigned char* if uint8_t exists? [duplicate]如果 uint8_t 存在,uint8_t* 是否等同于 unsigned char*? [复制]
【发布时间】:2021-01-21 16:34:43
【问题描述】:

如果uint8_t 存在,指向uint8_t 的指针是否等同于指向unsigned char 的指针?意味着它可以用于访问任何对象,并且在访问不同的对象时不会导致UB。我知道这条规则:

int intVar=0;
unsigned char *charPtr=&intVar; //completely valid and does not cause UB
printf("%X ",*charPtr); //this is also valid and does not cause UB

struct SomeStruct_T structVar={};
int *intPtr=&structVar; //This causes UB

但是这个呢:

int intVar=0;
uint8_t *uint8Ptr=&intVar; //Is this valid?
printf("%X ",*uint8Ptr);   //If yes, is this also valid?

带有-Wincompatible-pointer-types 的GCC 会发出关于unsigned char *charPtr=&intVar;uint8_t *uint8Ptr=&intVar; 的警告,但使用演员表时,此警告就会消失。这没有回答问题。 uint8_t * 可能与unsigned char * 不同的系统可能没有,但标准是怎么说的?

这个问题是关于指向unsigned charuint8_t 的指针类型,而不是关于数据类型unsigned charuint8_t 本身。 unsigned char * 的一些基本属性可能适用于uint8_t *,也可能不适用于uint8_t *,例如能够访问任何与unsigned char 类型本身无关的对象。因此,这个问题不是链接的question 的重复。链接的问题也是关于C++的,但我不问C++,我的问题是关于C的。请不要将此问题标记为链接问题的重复,因为问题肯定不一样。

【问题讨论】:

  • 我认为int *intPtr=&structVar; //This causes UB 只要你不取消引用它就可以(不是UB)(我需要挖掘标准才能确定)。
  • @underscore_d 链接的问题是关于数据类型,而不是指针类型。
  • @underscore_d 请在标记重复之前阅读这两个问题,谢谢。另一个问题是关于 uint8_t vs unsigned char 而不是 uint8_t * vs unsigned char * 和链接的问题是关于 C++ 这个问题是关于 C 的。
  • 我可以正常阅读,谢谢。 C++ 只是从 C 继承这些类型,指针的行为/有效性基于它们指向的类型,所以这对我来说似乎是一个明显的骗局。显然,另一个投票关闭重复的用户也同意了,所以我不能是唯一的。

标签: c pointers language-lawyer


【解决方案1】:

证明:

标准断言sizeof(unsigned char)1

标准断言没有小数大小。

标准不允许uint8_t 有填充位。

标准不允许unsigned char 有填充位。

因此:

根据鸽巢原则,uint_8 中不能有两个 unsigned chars。

uint_8 的大小必须为 1。

因此定义了unsigned charuint8_tuint8_tunsigned char 的位传送。

但是,您的代码并不完全有效,因为当您将指向 int 的指针转换为指向 unsigned char 的指针时,您采用了字节序依赖关系。在 C 中,指针转换是可传递的,除非将函数指针转换为非函数指针或从函数指针转换为非函数指针,因此我们可以分析一下,就好像您直接从 int * 转换为 unsigned char *。*

*这仅适用于演员表。通过 union 或 memcpy 进行 Blitting 可以解决这个问题。

【讨论】:

  • 不一定。可能是系统具有 16 位和 128 KiB RAM 的本机数据。在这样的系统上,char *void * 指针需要 2 个字(2*16 位)。也许编译器将所有可能的 uint8_t 变量(包括堆栈和堆)放在较低的 64 KiB 中,因此 uint8_t * 指针只需要 1 个字而不需要 2 个字,并且使 uint8_t * 无法访问所有内容。
  • @12431234123412341234123:你忘了malloc()。运行时不可能进行这种优化,因为它不知道 malloc() 是否正在分配 uint8_t。
  • 我说的是包括栈和堆。请记住,有些系统没有malloc()。独立环境不需要提供malloc()
  • @12431234123412341234123 6.3.2.3/7 怎么样:“指向对象类型的指针可能会转换为指向不同对象类型的指针。如果生成的指针未正确对齐 68) 对于引用的类型,行为未定义。否则,当再次转换回来时,结果将与原始指针比较。"? unsigned charuint8_t 肯定有相同的对齐方式,所以指针值可以双向转换?
  • @12431234123412341234123 如果CHAR_BITS > 8 然后没有uint8_t
猜你喜欢
  • 2013-04-14
  • 1970-01-01
  • 2011-10-23
  • 2011-06-02
  • 2012-03-20
  • 2013-09-01
  • 2021-07-11
  • 1970-01-01
相关资源
最近更新 更多