我想知道是否有任何事情可以阻止在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/

10-11 22:10
查看更多