Reputation: 9466
Running this:
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
template< int PathLength >
constexpr const int startfindlastslash(const char (&path)[PathLength]) {
return PathLength;
}
int main(int argc, char const *argv[])
{
STATIC_ASSERT( startfindlastslash( "cppdebugger/test_debugger.cpp" ) == 11 );
}
You got:
g++ -o main.exe --std=c++14 test_debugger.cpp
test_debugger.cpp: In function ‘int main(int, const char**)’:
test_debugger.cpp:1:28: error: static assertion failed: startfindlastslash( "cppdebugger/test_debugger.cpp" ) == 11
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
^
test_debugger.cpp:10:5: note: in expansion of macro ‘STATIC_ASSERT’
STATIC_ASSERT( startfindlastslash( "cppdebugger/test_debugger.cpp" ) == 11 );
^~~~~~~~~~~~~
clang++ -Xclang -ast-print -fsyntax-only --std=c++14 test_debugger.cpp > main.exe
test_debugger.cpp:10:5: error: static_assert failed due to requirement 'startfindlastslash("cppdebugger/test_debugger.cpp") == 11' "startfindlastslash(
\"cppdebugger/test_debugger.cpp\" ) == 11"
STATIC_ASSERT( startfindlastslash( "cppdebugger/test_debugger.cpp" ) == 11 );
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test_debugger.cpp:1:28: note: expanded from macro 'STATIC_ASSERT'
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
^ ~~~~~~~~~~~
1 error generated.
The compiler does not tell which one was the value it was supposed to get, it only says the value is not equal.
Upvotes: 3
Views: 4051
Reputation: 4655
I often find it useful to wrap static_asserts
in a function template. Then the compiler will print at least the function template parameters in the error message. If you combine this strategy with the value template approach of @Phil1970, you get pretty decent results.
When compiled with GCC, the following snippet prints the error message containing your values: In instantiation of 'constexpr void assert_equal(const_val<T, A>, const_val<U, B>) [with T = int; T A = 30; U = int; U B = 11]'
Clang is even better: <source>:13:5: error: static_assert failed due to requirement '30 == 11' "Values are not equal!"
.
#define MAKE_CONST(x) const_val<decltype(x), x>{}
#define STATIC_ASSERT_EQUAL(x, y) assert_equal(MAKE_CONST(x), MAKE_CONST(y));
template<typename T, T val>
struct const_val {
constexpr const_val() = default;
constexpr const_val(T v) {}
};
template<typename T, T A, typename U, U B>
constexpr void assert_equal(const_val<T, A>, const_val<U, B>) {
static_assert(A == B, "Values are not equal!");
}
template< int PathLength >
constexpr const int startfindlastslash(const char (&path)[PathLength]) {
return PathLength;
}
int main(int argc, char const *argv[])
{
STATIC_ASSERT_EQUAL(startfindlastslash( "cppdebugger/test_debugger.cpp" ), 11);
}
It's not exactly the syntax you were using and it involves an additional macro for convenience, but hopefully it's sufficient for your purpose...
Live code here.
Upvotes: 3
Reputation: 16680
[ This is not really an answer to "How to make static_assert print the value", but rather an explanation of why the OP is getting the behavior that he is. ]
Pre-c++17, static_assert
takes two parameters.
The first is the expression to be evaluated, and the second is the message to be printed when the expression does not evaluate to true.
When you define your STATIC_ASSERT
macro, you are giving static_assert
the message that you want printed - and it is printing that message for you.
Upvotes: 2