我想知道是否有任何事情可以阻止在ANSI C中执行此操作(或者在C99之前具有严格别名规则的任何事物)。
const int n = 1000;
double *a = (double *) malloc(n * sizeof(double));
// Weird aliasing
a = (double *) (&a);
f(a, n);
free(a);
这个问题来自以下事实:英特尔编译器确实将以下代码矢量化
void f(double *a, int n) {
int k;
for (k = 0; k < n; ++k) {
a[k] = a[k] + 1.0;
}
}
没有-ansi-aliasing选项(默认情况下,英特尔编译器不使用严格的别名规则)。我的猜测是,不应像前面的代码那样更改第一个循环中指向的内容。
弗朗索瓦
说明:由于经常有人对此原因进行解释,因此您可以在“违反类型规则”部分中的http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html上阅读Chris Lattner的帖子之一。在我看来,他正在使用严格的别名规则,因此使用C99声明他所做的操作无效。
最佳答案
否。a
具有类型double*
。因此&a
具有类型double**
。您正在将double**
强制转换为double*
。任何版本的C都不允许这样做。
例如在C89中,请参见section 3.3:
一个对象只能通过一个左值访问其存储值
具有以下类型之一:[28]
对象的声明类型,
对象声明类型的限定版本,
一个类型,它是与对象的声明类型相对应的有符号或无符号类型,
类型是与对象的声明类型的限定版本相对应的有符号或无符号类型,
成员中包括上述类型之一的集合或联合类型(递归地包括
子集合或包含的联合),或
字符类型。
[脚注28]此列表的目的是指定对象可能会别名也可能不会别名的那些情况。
关于c - ANSI C中的别名:是否允许= =(double *)(&a),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25242990/