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



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

最新更新