假设我有:

char * bufPtr = ...; // points into a char array with at least sizeof(void *) chars remaining
void *ptr1 = ...;
void *ptr2;

假设bufPtr正确对齐,这些线是

*(void **)bufPtr = ptr1; // (1)
ptr2 = *(void **)bufPtr; // (2)

合法吗?我知道char *可以成为任何东西的别名,但这一额度会不会反过来呢?

UPDATE:我正在研究的代码库是用C编写的,所以这是我最感兴趣的语言(如果我只能得到一个答案的话).我以为C和C++在这一点上是相似的,但也许我错了.

推荐答案

我知道char*可以成为任何东西的别名,但这种允许会不会反过来呢?

TLDR:

不是的.在不违反严格别名的情况下,您不能将[un[signed]] char数据视为任何其他类型.

然而,untyped内存是不同的.can通过赋值将无类型内存视为一种新类型.

Full Answer:

char *bufptr分,投到void **

(void **)bufPtr

可能违反6.3.2.3 Pointers, paragraph 7:

指向对象类型的指针可以被转换为指向不同对象类型的指针.如果结果指针未正确对齐被引用的类型,则行为未定义.

请注意,不必取消引用指针即可调用未定义的行为--仅creating个未对齐的指针就足以调用未定义的行为.

使用为取消引用的指针赋值

*(void **)bufPtr = ptr1;

可能违反严格锯齿,也可能不违反严格锯齿,具体取决于bufptr实际指向的内容.

从 comments 移动到聊天,记忆一直被描述为"未输入的".在这种情况下,这样的赋值不违反严格的别名.

然而,该存储器的使用的history可能会影响该存储器是否保持非类型化.请参见Does C strict aliasing make untyped static memory pools impossible?.请特别注意this answer点:

这样的分配器在strictly conformingC下是不能实现的,strictly conformingC是不依赖于未指定的、未定义的或实现定义的行为的C代码(并且不超过任何最小实现限制).用conformingC编写这样的分配器是完全可能的,它是带扩展的C.

如果使用GCC,我会用-fno-strict-aliasing-fno-ipa-strict-aliasing编译分配器代码,如果不使用,我会用等价的代码编译.请参见https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-fstrict-aliasing.

C++相关问答推荐

获取二维数组的最大元素

如何确保内存分配在地址附近?

在使用GTK 4 Columnview列表模型时,如何为多列添加排序函数.C编码,Linux/GNOME环境

括号中的堆栈实现错误问题

为什么输出不是从上到下C

从组播组地址了解收到的数据包长度

堆栈在作用域阻塞后会被释放吗?

C由四个8位整数组成无符号32位整数

为静态库做准备中的奇怪行为

如何在C中使数组变量的值为常量?

处理来自浏览器的HTTP请求

这个空指针类型的转换是有效代码还是恶意代码?

试图创建一个基本的Word克隆,但遇到了障碍

不带Malloc的链表

具有正确标头的C struct 定义问题

STM32 FATFS用户手册(Um1721)中的代码正确吗?

区分MySQL C界面中的文本和BLOB字段

不兼容的整数到指针转换传递';char';到类型';常量字符*

I';我试着从.txt文件中读取文本,并用c计算其中的单词数量

如何不断地用C读取文件?