C 保证重新 : Pointers to Void and Character Types, 类型转换

标签 c casting language-lawyer void-pointers char-pointer

我尽最大努力阅读了 C 规范(主要是 C99),这让我认为在适用于 void * 的隐式转换行为的情况下进行强制转换(或隐式转换)是有效的,这些类型中的任何一种:

void *, char *, signed char *, unsigned char *

我希望这不会触发未定义的行为,并且保证这些指针具有相同的底层表示。

因此,应该可以采用这四种类型中任何一种的指针,该指针已经指向可以合法取消引用的地址,类型转换和/或将其分配给三个 char 类型指针之一,然后取消引用它访问相同的内存,唯一的区别是您的代码是否将该位置的数据视为 charsigned charunsigned char.

这是正确的吗?是否有任何版本的 C 标准(在预标准化 C 中缺少 void * 类型无法承受)这不是真的?

附言我相信这个问题在传递许多其他问题时得到了零碎的回答,但我从未见过一个明确说明/确认的明确答案。

最佳答案

Consequently, it should be possible to take a pointer of either one of those four types that is already pointing to an address which can be legally dereferenced, typecast and/or assign it to one of the three char type pointers, and dereference it to access the same memory, with the only difference being whether your code will treat the data at that location as a char, signed char, or unsigned char.

这是正确的。事实上,您可以获取指向任何 类型对象的有效指针,并将其转换为这三种类型中的一些并访问内存。

您正确地提到了有关 void *char * 等具有相同表示和对齐要求的规定,但这实际上无关紧要。那指的是指针本身的属性,而不是被指向的对象的属性。

没有违反严格的别名规则,因为它包含一个字符类型可用于读取或写入任何对象的明确规定。

请注意,例如,如果我们有 signed char ch = -2; 或任何其他负值,则 (unsigned char)ch 可能不同于 *(unsigned char *)&ch。在具有 8 位字符的系统上,前者保证为 254 但后者可以是 254253 130 取决于使用的编号系统。

关于C 保证重新 : Pointers to Void and Character Types, 类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32578388/

相关文章:

c - 问题 fork() 不执行进程

c - 将包含动态数组的结构写入二进制文件 (C)

c# - 使用 BitConverter 在 C# 中进行快速转换,它能更快吗?

c++ - 为什么仅仅因为有一个用户定义的析构函数,复制构造函数就不是微不足道的了?

C - 使用 select() 时如何限制服务器中的入站连接数

c - 如何以可读的方式使用 C 初始化寄存器中的位

Haskell:具有逻辑上不同 bool 值的类型安全

c# - 使用 PullFilter 删除数组元素时出现异常

c++ - 为什么 C++ 允许重复的 + 运算符,例如 x = 1++++++++ 2;

c++ - C++ 标准中的什么措辞允许 static_cast<non-void-type*>(malloc(N));去工作?