我有一个关于使用 #pragma 消息打印 #defines 评估值的快速问题。我在Visual Studio 2008中使用msvc++。
下面是一个简化的示例:
#define __STR2__(x) #x
#define __STR1__(x) __STR2__(x)
#define WIDTH 10
#define HEIGHT 10
#define AREA (WIDTH * HEIGHT)
#pragma message("Area is: " __STR1__(AREA))
现在当我编译时,我得到以下输出:
>Area is: (10 * 10)
这不是我想要的。有没有办法打印出 #define 表达式的计算,以便我得到:
>Area is: 100
在编译期间。也许这是不可能的。最终,我希望能够在评估值太大时导致编译器错误。即
#if(AREA > 1000)
#pragma message(__ERROR__)
#endif
我的一些 #defines 使用sizeof()
我相信在评估条件时本身会导致问题 - 但这对未来来说是一个问题!
我看了下面的帖子如何在 gcc 中编译时显示 #define 的值,只要#define
定义为值而不是其他 #defines 的串联,就可以了。
预处理器不会为你做数学运算,它只能以文本方式替换标记和扩展宏。
如果你想在编译期间计算该值,你应该选择constexpr
(http://en.cppreference.com/w/cpp/language/constexpr,更准确地说,这将提示编译器在编译时计算它(
#include <iostream>
#define WIDTH 10
#define HEIGHT 10
template<int a, int b>
constexpr int getArea() {
static_assert(a*b < 1000, "Area is too big");
return a*b;
}
const int area = getArea<WIDTH, HEIGHT>();
int main(void) {
std::cout << area;
}
例
如果面积太大,static_assert将检查该区域。
预编译器可以在#if
语句中执行有限的数学运算。这可能足以满足您的需求:
#define WIDTH 10
#define HEIGHT 10
#define AREA (WIDTH * HEIGHT)
#if AREA > 1000
#error Oh bad, oh bad, oh bad
#endif
对于更复杂的数学,我会支持Marco A.所说的话,但你不需要在模板或其他任何东西中使用它。你可以把它和你所有的#define
一起放上去,例如:
#define WIDTH 10
#define HEIGHT 10
#define AREA (WIDTH * HEIGHT)
#define __ERROR__ "Oh bad, oh bad, oh bad"
static_assert(AREA < 1000, __ERROR__);
甚至更简单:static_assert(WIDTH * HEIGHT < 1000, "Oh bad, oh bad, oh bad");