【问题标题】:Print fully evaluated result of #define during compilation using #pragma message()使用#pragma message() 在编译期间打印#define 的完全评估结果
【发布时间】:2014-10-17 12:08:50
【问题描述】:

我有一个关于使用#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(),我认为这在评估条件时会导致问题 - 但这是未来的问题!

我查看了以下帖子How do I show the value of a #define at compile time in gcc,只要将#define 定义为一个值,而不是其他#defines 的串联,就可以了。

【问题讨论】:

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


    【解决方案1】:

    预处理器不会为您做数学运算,它只能替换标记并以文本方式扩展宏。

    如果您想在编译期间计算该值,您应该选择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 会检查区域是否太大。

    【讨论】:

    • 谢谢马可。我相信这种方法可以评估区域是否太大——即使宏包含 sizeof() 语句,但我认为它不允许我在编译期间打印出“区域”的值?或者也许我错过了一些东西。正如你所说的预处理器只能输出字符串。
    • @user3581793 如果条件不满足,这将在编译时打印。你的意思是在编译时打印一些东西并让编译继续进行吗?这是一个不同的问题,有一些“黑客”可以做到这一点:blogs.msdn.com/b/vcblog/archive/2007/05/17/…。不过我不推荐这些。
    • 是的,我想是的。本质上,我想打印出“面积”的值,而不管它是否满足太大的条件。因此,如果该值小于 1000,它将打印出例如 Area is 900 并且编译将继续。如果区域太大,断言将停止编译。而且看起来static_assert()只是较新的 C++11 标准的一部分——我不能用于这个项目。
    【解决方案2】:

    预编译器可以在#if 语句中进行有限的数学运算。这可能足以满足您的需求:

    #define WIDTH     10
    #define HEIGHT    10
    #define AREA      (WIDTH * HEIGHT)
    #if AREA > 1000
    #error Oh bad, oh bad, oh bad
    #endif
    

    对于更复杂的数学,我会支持Marco A. 所说的,但您不需要在模板或任何东西中使用它。 你可以把它和你所有的#defines 放在一起,例如:

    #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 &lt; 1000, "Oh bad, oh bad, oh bad");

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-04
      • 1970-01-01
      • 2011-09-27
      • 1970-01-01
      相关资源
      最近更新 更多