2

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.

Community
  • 1
  • 1

2 Answers2

1

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.

Marco A.
  • 43,032
  • 26
  • 132
  • 246
  • Thank you Marco. I believe this approach would work in terms of evaluating whether or not the Area is too large - even if the macros contain sizeof() statements, however I don't think it would allow me to print out the value of 'Area' during compilation? Or perhaps I'm missing something. As you say the pre-processor can only output strings. – user3581793 Oct 17 '14 at 23:37
  • @user3581793 This will print at compile-time if the condition isn't met. Do you mean printing at compile-time something and let the compilation proceed? That is a different issue and there are some "hacks" to do it: http://blogs.msdn.com/b/vcblog/archive/2007/05/17/diagnosing-hidden-odr-violations-in-visual-c-and-fixing-lnk2022.aspx . I wouldn't recommend those though. – Marco A. Oct 18 '14 at 07:12
  • Yes I think so. Essentially I would like to print out the value of 'Area' regardless of meeting it the condition of being too large. So if the value was less than 1000 it would print out for instance `Area is 900` and compilation would continue. Assert would stop compilation if area was too large. Also it looks like `static_assert()`is only part of the newer C++11 standard - which I can't use for this project. – user3581793 Oct 19 '14 at 20:57
0

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

Community
  • 1
  • 1
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288