使用#pragma message()在编译期间打印#define的完全评估结果

时间:2014-10-17 12:08:51

标签: c++ visual-c++ c-preprocessor pragma

我有一个关于使用#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>

2 个答案:

答案 0 :(得分:1)

预处理器不会为你做数学,它只能用文本方式替换tokens和扩展宏。

如果你想在编译期间计算这个值,你应该去constexprhttp://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;
}

Example

如果区域太大,

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");