C99中是否允许这种冗余加载/存储优化?

zr.*_*zr. 12 c optimization standards

考虑以下:

extern void bar(int *restrict);

void foo(int *restrict p) {
  int tmp;
  bar(&tmp);
  *p = tmp;
}
Run Code Online (Sandbox Code Playgroud)

C99规范是否允许优化foo以下?

extern void bar(int *restrict);

void foo(int *restrict p) {
  bar(p);
}
Run Code Online (Sandbox Code Playgroud)

我在-O3模式下尝试了gcc,Clang和Intel Compiler,并且都没有生成反映上述优化的代码.这让我怀疑这种优化打破了规范.如果不允许,那么它在规范中的含义是什么?

注意:我的问题受到这个SO问题的启发

rid*_*ish 18

答案是肯定的否定,这是不允许的.

考虑如果foo和bar相互递归会发生什么.例如,这个实现bar:

void bar(int *restrict p)
{
    static int q;
    if (p == &q) {
        printf("pointers match!\n");
    } else if (p == NULL) {
        foo(&q);
    }
}
Run Code Online (Sandbox Code Playgroud)

bar永远不要取消引用p,所以限制限定符是无关紧要的.很明显,静态变量q不能与tmpfoo中的自动变量具有相同的地址.因此,foo无法将其参数传递回bar,并且不允许给定的优化.