我无法解释这个程序的执行行为:
#include <string>
#include <cstdlib>
#include <stdio.h>
typedef char u8;
typedef unsigned short u16;
size_t f(u8 *keyc, size_t len)
{
u16 *key2 = (u16 *) (keyc + 1);
size_t hash = len;
len = len / 2;
for (size_t i = 0; i < len; ++i)
hash += key2[i];
return hash;
}
int main()
{
srand(time(NULL));
size_t len;
scanf("%lu", &len);
u8 x[len];
for (size_t i = 0; i < len; i++)
x[i] = rand();
printf("out %lu\n", f(x, len));
}
Run Code Online (Sandbox Code Playgroud)
因此,当使用带有gcc的-O3编译并使用参数25运行时,它会引发段错误.没有优化它工作正常.我已经对它进行了反汇编:它正在进行矢量化,并且编译器假定 …
我知道gcc有一个选项-Wcast-align,只要指针被转换就会发出警告,以便增加目标所需的对齐.
这是我的计划:
char data[10];
int ptr = *((int *)data);
Run Code Online (Sandbox Code Playgroud)
在我的机器上,数据的对齐要求是1,而ptr是8.
为什么我没有收到警告?
可能是因为我正在为x86编译吗?
这个问题是我之前问过的问题的延伸。但是,经过一段时间后,我发现我的一些关于两个指针之间的转换行为的概念仍然很模糊。
为了便于讨论,我首先对主机实现做如下假设:
sizeof(int): 4, _Alignof(int): 4sizeof(double): 8, _Alignof(double): 8void *ptr = malloc(4096); // (A)
*(int *) ptr = 10; // (B)
/*
* Does the following line have undefined behavior
* or violate strict aliasing rules?
*/
*(((double *) ptr) + 2) = 1.618; // (C)
// now, can still read integer value with (*(int *) ptr)
Run Code Online (Sandbox Code Playgroud)
以我目前的理解,答案是否定的。
根据 C11 的 [6.3.2.3 #7]:
指向对象类型的指针可以转换为指向不同对象类型的指针。如果结果指针未针对引用类型正确对齐,则行为未定义。...
和 C11 的 …