gcc 5和clang 3.6都不会在restrict限定符的约束被违反的情况下发出警告,即使在调用时也是如此-Wall.请考虑以下代码片段:
extern void f(char *restrict p, char *restrict q);
void g(char *p)
{
f(p, p);
}
Run Code Online (Sandbox Code Playgroud)
天真地,我希望可以静态地确定违规行为,我期待这-Wall会发出警告.我在某个地方错过了一面旗帜,还是在发出一些我没有看到警告的问题?
请考虑以下代码:
void doesnt_modify(const int *);
int foo(int *n) {
*n = 42;
doesnt_modify(n);
return *n;
}
Run Code Online (Sandbox Code Playgroud)
其中定义对doesnt_modify编译器不可见.因此,它必须假定,doesnt_modify将对象n指向更改并且必须*n在return(最后一行不能被替换return 42;)之前读取.
假设,doesnt_modify不修改*n.我考虑了以下内容以允许优化:
int foo_r(int *n) {
*n = 42;
{ /* New scope is important, I think. */
const int *restrict n_restr = n;
doesnt_modify(n_restr);
return *n_restr;
}
}
Run Code Online (Sandbox Code Playgroud)
这样做的缺点是调用者doesnt_modify必须告诉编译器*n没有被修改,而不是函数本身可以通过其原型告诉编译器.简单地restrict将参数限定doesnt_modify在声明中是不够的,参见 "是顶级volatile还是restrict重要的?".
当与编译gcc -std=c99 …
我正在探索如何基于函数签名在C99中简单循环的不同实现自动矢量化。
这是我的代码:
/* #define PRAGMA_SIMD _Pragma("simd") */
#define PRAGMA_SIMD
#ifdef __INTEL_COMPILER
#define ASSUME_ALIGNED(a) __assume_aligned(a,64)
#else
#define ASSUME_ALIGNED(a)
#endif
#ifndef ARRAY_RESTRICT
#define ARRAY_RESTRICT
#endif
void foo1(double * restrict a, const double * restrict b, const double * restrict c)
{
ASSUME_ALIGNED(a);
ASSUME_ALIGNED(b);
ASSUME_ALIGNED(c);
PRAGMA_SIMD
for (int i = 0; i < 2048; ++i) {
if (c[i] > 0) {
a[i] = b[i];
} else {
a[i] = 0.0;
}
}
}
void foo2(double * restrict a, const double * restrict b, …Run Code Online (Sandbox Code Playgroud) simd c99 variable-length-array restrict-qualifier auto-vectorization