This is super-ugly, but it displays both the name of the expression and its meaning in a noticeable, albeit terrible, format:
constexpr int I = 8 % 3; #define CONCATENATE( s1, s2 ) s1 ## s2 #define EXPAND_THEN_CONCATENATE( s1, s2 ) CONCATENATE( s1, s2 ) template<int i> class The_expression_named_in_the_previous_error_has_value{ static_assert(i != i, ""); }; #define ERROR_PRINT(_expr) \ EXPAND_THEN_CONCATENATE(In_the_next_error_you_will_find_the_value_of_the_expression__, _expr); \ The_expression_named_in_the_previous_error_has_value<I>(); int main() { ERROR_PRINT(I); }
This gives (with GCC 6):
main.cpp: In function 'int main()': main.cpp:11:25: error: 'In_the_next_error_you_will_find_the_value_of_the_expression__I' was not declared in this scope EXPAND_THEN_CONCATENATE(In_the_next_error_you_will_find_the_value_of_the_expression__, _expr); \ ^ main.cpp:3:45: note: in definition of macro 'CONCATENATE' #define CONCATENATE( s1, s2 ) s1 ## s2 ^ main.cpp:11:1: note: in expansion of macro 'EXPAND_THEN_CONCATENATE' EXPAND_THEN_CONCATENATE(In_the_next_error_you_will_find_the_value_of_the_expression__, _expr); \ ^ main.cpp:15:5: note: in expansion of macro 'ERROR_PRINT' ERROR_PRINT(I); ^ main.cpp: In instantiation of 'class The_expression_named_in_the_previous_error_has_value<2>': main.cpp:15:5: required from here main.cpp:7:61: error: static assertion failed: class The_expression_named_in_the_previous_error_has_value{ static_assert(i != i, ""); };
But I'm sure this can be greatly improved with some kind of constexpr-string-trickery.
source share