Given this test program:
#include <cassert>
#include <string>
#include <type_traits>
const std::string& const_string = "bla";
std::string const & string_const = "blabla";
static_assert(std::is_same<decltype(const_string), decltype(string_const)>::value, "Uhoh");
int main()
{
assert(std::is_same<decltype(const_string), decltype(string_const)>::value);
}
Which asserts that two types are the same at compile-time and at runtime using C's assert. All of Clang, MSVC2015, and GCC report the same error, so I'm quite sure it's me:
main.cpp:13:49: error: too many arguments provided to function-like macro invocation
assert(std::is_same<decltype(const_string), decltype(string_const)>::value);
^
/usr/include/assert.h:91:10: note: macro 'assert' defined here
# define assert(expr) \
^
I'm just not seeing two arguments in the assert
. What's more, the static_assert
works just fine... So what is going on here?
The assert() function tests the condition parameter. If it is false, it prints a message to standard error, using the string parameter to describe the failed condition. It then sets the variable _assert_exit to one and executes the exit statement. The exit statement jumps to the END rule.
In the C Programming Language, assert is a macro that is designed to be used like a function. It checks the value of an expression that we expect to be true under normal circumstances. If expression is a nonzero value, the assert macro does nothing.
Assertions in C/C++ Following is the syntax for assertion. void assert( int expression ); If the expression evaluates to 0 (false), then the expression, sourcecode filename, and line number are sent to the standard error, and then abort() function is called.
The C preprocessor does not recognise C++ template syntax, therefore template brackets <
and >
are not viewed as grouping tokens by the preprocessor, they're seen as simple characters.
This means that the preprocessor will view the comma between the template parameters as a macro parameter separator, like this:
assert(
std::is_same<decltype(const_string),
decltype(string_const)>::value);
To force the preprocessor to see your expression as a single statement, simply wrap your assert
parameter in an additional set of brackets:
assert((std::is_same<decltype(const_string), decltype(string_const)>::value));
static_assert
doesn't have this limitation because it is a C++ keyword, rather than a preprocessor macro like assert()
. This means it fully supports C++ syntax and sees the template parameters correctly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With