Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does these few lines do as a small test framework in C++?

Tags:

c++

c++11

Hi I am reading through the implementation of std::optional here and I found the following lines in its unit testing files.

struct caller {
    template <class T> caller(T fun) { fun(); }
};
# define CAT2(X, Y) X ## Y
# define CAT(X, Y) CAT2(X, Y)
# define TEST(NAME) caller CAT(__VAR, __LINE__) = []

I don't really understand what do these lines do. caller seems to be a template to invoke functions, but how can it be used as caller CAT ...? What does X ## Y mean here? Later in the file, the user define unit tests using TEST, but they do not appear in any executable code (I mean they are not called in main function at least), so I am not even sure if the compiled binary actually run the tests. Could you explain what is going on here? Thanks!

Edit: pretty sure the tests are executed when I run the binary, but how is that achieved?

like image 784
Bob Fang Avatar asked Jul 24 '17 21:07

Bob Fang


1 Answers

You can look at the output after the preprocessing ( -E for gcc)...

This is the code where I added a usage of the macro:

struct caller {
    template <class T> caller(T fun) { fun(); }
};
# define CAT2(X, Y) X ## Y
# define CAT(X, Y) CAT2(X, Y)
# define TEST(NAME) caller CAT(__VAR, __LINE__) = []

TEST(disengaged_ctor) { foo(); };

after preprocessing the last line turns to:

caller __VAR10 = []{ foo(); };

I am a bit puzzled about the __VAR and the unused NAME *. However, []{ foo(); } is a lambda that when used to create a caller gets invoked in the callers constructor.

* = I guess the idea is the following: Suppose you get a error message saying there is an error in __VAR10 then on line 10 you find TEST(disengaged_ctor), ie. the NAME of the failed test.

like image 90
463035818_is_not_a_number Avatar answered Oct 26 '22 23:10

463035818_is_not_a_number