考虑到此代码,VC9不会检测别名:
typedef struct { int x, y; } vec_t;
void rotate_cw(vec_t const *from,
vec_t *to)
{
/* Notice x depends on y and vice versa */
to->x = from->y;
to->y = -from->x;
}
/* ... */
vec_t a, b;
rotate_cw(&a, &b); /* OK, no aliasing */
rotate_cw(&a, &a); /* FAIL, aliasing is not detected */
显而易见的解决方法是使用临时的:
void rotate_cw(vec_t const *from,
vec_t *to)
{
int temp = from->x;
to->x = from->y;
to->y = -temp;
}
这是标准行为吗?我期待编译器,除非被告知,否则会假设两个指针都可能是别名。
答案 0 :(得分:4)
尝试在参数之前添加__restrict,似乎是任何人发现让MSVC发出任何警告的唯一方法。
答案 1 :(得分:4)
编写的代码完全有效,在C89或C99中。这是模糊的,但编译器没有任何内容可以诊断,因此它不会被诊断出来。
如果在函数的两个参数上使用C99和'restrict',那么如果编译器支持C99,则会出错。 AFAIK,当前版本的MSVC尚未完全支持C99。
答案 2 :(得分:0)
在C99发明restrict
限定符之前,一些C编译器包含了优化选项,可以指导它们对指针使用做出某些假设;我在这些编译器中看到的手册明确警告说,这样的优化不符合标准,并且可以任意使用某些特定构造的代码,这些构造的行为由标准定义,其行为方式是与标准和程序员的意图相反。从手册的角度来看,优化告诉编译器编译C的一个子集,它没有定义在C中定义的某些极端情况的行为,但是这将允许为这些情况生成更有效的代码确实定义了。