Why does this “call” claim to see only two arguments instead of one?

Provided with 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 states that the two types are the same at compile time and at runtime using C assert. All Clang, MSVC2015 and GCC report the same error, so I'm sure it it :

 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 just don't see two arguments in assert . What else, static_assert works just fine ... So what is going on here?

+6
source share
2 answers

The C preprocessor does not recognize the syntax of the C ++ template, so the template brackets < and > not considered tokens by the preprocessor, they are treated as simple characters.

This means that the preprocessor will look at the comma between the template parameters as a macro parameter separator, for example:

 assert( std::is_same<decltype(const_string), decltype(string_const)>::value); 

To make the preprocessor see your expression as a single statement, simply add your assert parameter to an additional set of brackets:

 assert((std::is_same<decltype(const_string), decltype(string_const)>::value)); 

static_assert does not have this limitation because it is a C ++ keyword , not a preprocessor macro like assert() . This means that it fully supports C ++ syntax and correctly sees template parameters.

+4
source

This is because of the < and > tokens. They ruined the preprocessor. Remember that assert is a macro, not a function.

Do this (add an extra set of parentheses):

 assert((std::is_same<decltype(const_string), decltype(string_const)>::value)); ^ ^ 
+3
source

All Articles