我有一个例程,它使用适当大小的数组来处理额外的字节,将单精度数据数组提升为双精度:
void dpromote(const int n, double *x)
{
for (int i = n; i --> 0 ;) {
x[i] = ((float *)x)[i];
}
}
进入x
时应包含n
float
s,退出时应包含n
double
s:
void test_dpromote()
{
double e[] = {1, 2, 3, 4, 5, 6, 7};
float x[] = {1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0};
const int n = sizeof(e)/sizeof(e[0]);
dpromote(n, (void *) x);
/* memcmp(x, e, sizeof(e)) will return 0 when this works as expected */
}
我为什么要这样做?数字密集型代码中的混合精度迭代细化。出于这个问题的目的,您可以忽略原因,因为它确实无关紧要。
多个编译器可以dpromote
在启用严格别名的各种积极优化级别上处理逻辑。最近,一位编译器供应商(将保持匿名)决定重新索引我的循环,以便它是通过内存的前向遍历而不是向后遍历。如果你盯着代码半分钟,你会发现循环转换产生了完全的垃圾。
dpromote
启用所有 C99 严格混叠花哨的逻辑是否依赖于未定义的行为?我不明白为什么编译器会认为可以更改循环索引,除非代码正在做未定义的事情。