Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print result of a compile-time calculation in C++?

I've wrote several constexpr functions and use them in static_asserts to control some resource limits. But I'd like to not only enforce compile-time predicate but also to see the actual values calculated during normal compilation process or at least when assertion fails.

There are ways to print string messages during compilation, but what's about printing results of constexpr computations?

like image 375
Dmitry Vyal Avatar asked Mar 04 '15 10:03

Dmitry Vyal


1 Answers

Here is some code that exploits gcc's diagnostic messages to print values of interest after an assert message. To find the values of interest, you just need to search the error string for T x =:

#include <string>

template <class T, T x, class F>
void transparent(F f) { f(); }


template <bool B>
constexpr void my_assert() { 
    static_assert(B, "oh no");
}

template <int X>
void f() {
    transparent<int, X+7>([]{
        transparent<long, X*X*X>([]{
            my_assert<X+10==-89>(); });});
}

int main() {
//    f<3>();
    f<4>();
//    f<-99>();
}

Here is the error that it got me:

g++ h.cpp -std=c++11
h.cpp: In instantiation of ‘constexpr void my_assert() [with bool B = false]’:
h.cpp:16:34:   required from ‘f() [with int X = 4]::__lambda0::__lambda1’
h.cpp:15:35:   required from ‘struct f() [with int X = 4]::__lambda0::__lambda1’
h.cpp:16:38:   required from ‘f() [with int X = 4]::__lambda0’
h.cpp:14:28:   required from ‘struct f() [with int X = 4]::__lambda0’
h.cpp:16:41:   required from ‘void f() [with int X = 4]’
h.cpp:21:10:   required from here
h.cpp:9:5: error: static assertion failed: oh no
     static_assert(B, "oh no");
     ^
h.cpp:4:6: error: ‘void transparent(F) [with T = long int; <b>T x = 64l</b>; F = f() [with int X = 4]::__lambda0::__lambda1]’, declared using local type ‘f() [with int X = 4]::__lambda0::__lambda1’, is used but never defined [-fpermissive]
 void transparent(F f) { f(); }
      ^
h.cpp:4:6: error: ‘void transparent(F) [with T = int; <b>T x = 11</b>; F = f() [with int X = 4]::__lambda0]’, declared using local type ‘f() [with int X = 4]::__lambda0’, is used but never defined [-fpermissive]

Note that bolded parts

like image 140
tohava Avatar answered Sep 17 '22 11:09

tohava