user3581793
user3581793

Reputation: 31

Print fully evaluated result of #define during compilation using #pragma message()

I have a quick question regarding printing the evaluated values of #defines using #pragma message. I'm using msvc++ in Visual Studio 2008.

Below is a simplified example:

#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))

Now when I compile I get the following output:

>Area is: (10 * 10)

This is not exactly what I want. Is there any way to print out the evaluation of a #define expression so that I get:

>Area is: 100

during compilation. Perhaps this is not possible. Eventually I want to be able to cause a compiler error if the evaluated value is too large. i.e.

#if(AREA > 1000)
#pragma message(__ERROR__)
#endif

Some of my #defines use sizeof() which I believe causes issues in itself when evaluating conditionals - but that's a problem for the future!

I looked at the following post How do I show the value of a #define at compile time in gcc which is fine as long as the #define is defined as a value, and not a concatenation of other #defines.

Upvotes: 2

Views: 2368

Answers (2)

Jonathan Mee
Jonathan Mee

Reputation: 38939

The precompiler can do limited math in #if statements. This may be sufficient for your needs:

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

For more complex mathematics I would second what Marco A. said but you don't need that in a template or anything. You can just put it up with all your #defines, for example:

#define WIDTH     10
#define HEIGHT    10
#define AREA      (WIDTH * HEIGHT)
#define __ERROR__ "Oh bad, oh bad, oh bad"
static_assert(AREA < 1000, __ERROR__);

Or even simpler: static_assert(WIDTH * HEIGHT < 1000, "Oh bad, oh bad, oh bad");

Upvotes: 0

Marco A.
Marco A.

Reputation: 43662

The preprocessor won't do math for you, it can only substitute tokens and expand macros in a textual way.

If you want to calculate that value during compilation you should go for constexpr (http://en.cppreference.com/w/cpp/language/constexpr, more precisely this will hint the compiler to calculate it at compile-time)

#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 will do the check for the area if it is too large.

Upvotes: 1

Related Questions