1

With template metaprogramming, the TD trick can be used to print the type of expressions as an error message at compile time.

This is really useful to debug templates. Is there a similar way to print values that are computed at compile-time?

anderas
  • 5,744
  • 30
  • 49

2 Answers2

3

Yes, and the code looks really similar: You declare (but not define) a template struct that has the value as a template parameter. By trying to instantiate it without defining it, you get a compiler error that spells out the constant value:

template <int val>
struct PrintConst;

PrintConst<12*34> p;

When compiling this code, g++ fails with the following error:

const-display.cpp:4:19: error: aggregate ‘PrintConst<408> p’ has incomplete type and cannot be defined
 PrintConst<12*34> p;
                   ^

Note that it shows both the expression 12*34, as well as the resulting value 408.

anderas
  • 5,744
  • 30
  • 49
  • 1
    How do you do this without breaking compilation? – SergeyA Dec 21 '18 at 15:57
  • @SergeyA AFAIK, there is no way, unless you are somehow able to cause a warning instead of an error. (Which might still break compilation when using -Werror or equivalent compile flags.) – anderas Dec 27 '18 at 15:56
3

You can use static_assert for this job too:

template<int val>
void static_print()
{
    static_assert(val & false, "");
}

int main()
{
    static_print<12*34>();
}

which output on g++:

x.cc: In instantiation of ‘void static_print() [with int val = 408]’:
x.cc:9:22:   required from here
x.cc:4:20: error: static assertion failed
  static_assert(val & false, "");

or in clang:

x.cc:9:2: note: in instantiation of function template specialization 'static_print<408>' requested here
    static_print<12*34>();
    ^
Amadeus
  • 10,199
  • 3
  • 25
  • 31
  • I originally thought about using static_assert, too, but it only printed the expression (like in the last line of your error message). I like the idea of using it inside a function as as a kind of indirection! I'm not quite sure which answer to accept - yours looks nicer to use, but mine is shorter to write (which might be handy if it is used as a quick&dirty debugging aid and removed from the code again afterwards)... – anderas Dec 27 '18 at 16:01
  • @anderas Just as a correction, both messages show the results, but gcc does not show the original expression. Anyway, I think you should accept the one that it is most compelling to you, or just does not accept anyone. What I like this answer is the fact that you can put any message that you want aside the test. – Amadeus Dec 27 '18 at 23:29