我想对pow2C进行如下定义。但我的编译器显示它(__tmpDouble__)已经定义。请帮我定义一下。
#ifndef pow2C
double __tmpDouble__;
#define pow2C(a) ((__tmpDouble__=(a))*(__tmpDouble__))
#endif
.
.
.
inline double calculateDistance(double *x, double *y, int NDims)
{
double d = 0;
for (int i = 0; i < NDims; i++)
// it is faster to calculate the difference once
d += pow2C(x[i] - y[i]);
return sqrt(d);
}
答案 0 :(得分:8)
如果您坚持编写宏,请为变量使用其他名称。但你的宏非常可怕。首先,对于并发调用,它不是线程安全的,因为线程将访问相同的临时变量。此外,大多数宏一般都是非常邪恶的(虽然有一些例外)。
然而,相同(也是性能方面)可以更容易实现(即使支持float
以及带有operator*
功能模板的其他类型:
template <typename T>
T square(const T &v) {
return v * v;
}
如果你想要一个宏,那么#define pow2C square
( sarcasm sign )。
答案 1 :(得分:5)
这是定义宏的一种可怕方式!您不应该将变量作为计算的一部分引入。相反,试试这个:
#define pow2C(a) ((a) * (a))
然而,宏对于这种计算是很糟糕的,因为它们可能效率低下并导致不必要的副作用。例如,如果您编码,它将扩展为:
(x[i] - y[i]) * (x[i] - y[i])
你做了两次减法的地方!
相反,使用C ++模板:
template<class T>
T pow2C(const T &value)
{
return value * value;
}
现在你只进行一次减法计算!
答案 2 :(得分:2)
我想只计算一次x [i] -y [i]并将其保存在变量中并使用它。
您已经只计算过一次。这一切都毫无意义。
如果您仍然坚持,则您输入的错误does not exist in this code 。
但是,你做的宏内容有问题,它会读取和写入表达式中的单个变量。结果未定义:
#include <iostream>
#include <cmath>
#include <array>
#ifndef pow2C
double __tmpDouble__;
#define pow2C(a) ((__tmpDouble__=(a))*(__tmpDouble__))
#endif
inline double calculateDistance(double *x, double *y, int NDims)
{
double d = 0;
for (int i = 0; i < NDims; i++)
// it is faster to calculate the difference once
d += pow2C(x[i] - y[i]);
return sqrt(d);
}
int main()
{
const size_t NUM_DIMS = 3;
std::array<double, NUM_DIMS> x{{5.0, 6.0, 7.0}};
std::array<double, NUM_DIMS> y{{1.2, 1.5, 9.0}};
std::cout << "Distance between x and y is: " << calculateDistance(&x[0], &y[0], NUM_DIMS) << '\n';
}
// g++-4.8 -std=c++11 -Wall -pedantic -pthread main.cpp && ./a.out
// main.cpp: In function 'double calculateDistance(double*, double*, int)':
// main.cpp:16:31: warning: operation on '__tmpDouble__' may be undefined [-Wsequence-point]
// d += pow2C(x[i] - y[i]);
// ^
// Distance between x and y is: 6.22013
所以,真的,我们回到不要这样做。
如果您仍然急于避免两次评估x[i] - y[i]
:
inline double calculateDistance(double* x, double* y, int NDims)
{
double d = 0;
for (int i = 0; i < NDims; i++) {
const double diff = x[i] - y[i];
d += diff * diff;
}
return sqrt(d);
}
如果您愿意,可以将乘法工作传递给另一个inline
实用程序函数,但这里不需要宏。