我有一个关于使用#pragma message打印#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()
我认为在评估条件时会导致问题 - 但这对未来是一个问题!
我查看了以下帖子How do I show the value of a #define at compile time in gcc,只要将#define
定义为值,而不是其他#defines的串联,就可以了。{/ p>
答案 0 :(得分:1)
预处理器不会为你做数学,它只能用文本方式替换tokens和扩展宏。
如果你想在编译期间计算这个值,你应该去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将检查该区域。
答案 1 :(得分:0)
预编译器可以在#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");