variadic-macros

Visual studio __VA_ARGS__ issue

£可爱£侵袭症+ 提交于 2019-12-03 04:00:37
I run cl /P test.cpp, the file and result is as following. test.cpp #define FiltedLog( ...) \ if (logDetail) \ MP_LOG(LOG_INFO, __VA_ARGS__); #define MP_LOG(level,fmt,...) \ BOOAT::LOG("MP", level, fmt, ##__VA_ARGS__) #define LOG(tag,level,fmt,...) \ Log::log(tag, level, "%s: " fmt, __PRETTY_FUNCTION__, ##__VA_ARGS__) int main () { FiltedLog ( "abc", 1, 2); } Cl /P test.cpp : #line 1 "test.cpp" int main () { if (logDetail) BOOAT::Log::log("MP", LOG_INFO, "%s: " "abc", 1, 2, __PRETTY_FUNCTION__ );; } I wonder why the __PRETTY_FUNCTION__ are put as the last arguments in the result. I assume the

A better LOG() macro using template metaprogramming

牧云@^-^@ 提交于 2019-12-03 01:03:07
问题 A typical LOG() macro-based logging solution may look something like this: #define LOG(msg) \ std::cout << __FILE__ << "(" << __LINE__ << "): " << msg << std::endl This allows programmers to create data rich messages using convenient and type-safe streaming operators: string file = "blah.txt"; int error = 123; ... LOG("Read failed: " << file << " (" << error << ")"); // Outputs: // test.cpp(5): Read failed: blah.txt (123) The problem is that this causes the compiler to inline multiple ostream

What does __VA_ARGS__ in a macro mean?

血红的双手。 提交于 2019-12-03 00:45:48
/* Debugging */ #ifdef DEBUG_THRU_UART0 # define DEBUG(...) printString (__VA_ARGS__) #else void dummyFunc(void); # define DEBUG(...) dummyFunc() #endif I've seen this notation in different headers of C programming, I basically understood it's passing arguments, but I didn't understand what this "three dots notation" is called? Can someone explain it with example or provide links also about VA Args? The dots are called, together with the __VA_ARGS__ , variadic macros When the macro is invoked, all the tokens in its argument list [...], including any commas, become the variable argument . This

A better LOG() macro using template metaprogramming

若如初见. 提交于 2019-12-02 16:23:12
A typical LOG() macro-based logging solution may look something like this: #define LOG(msg) \ std::cout << __FILE__ << "(" << __LINE__ << "): " << msg << std::endl This allows programmers to create data rich messages using convenient and type-safe streaming operators: string file = "blah.txt"; int error = 123; ... LOG("Read failed: " << file << " (" << error << ")"); // Outputs: // test.cpp(5): Read failed: blah.txt (123) The problem is that this causes the compiler to inline multiple ostream::operator<< calls. This increases the generated code and therefore function size, which I suspect may

Macro not expanded with direct call, but expanded with indirect

无人久伴 提交于 2019-12-02 13:22:59
问题 I've got the following macros #include <boost/preprocessor.hpp> #define DB_FIELD(...) BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) #define DB_TOFIELD(type,name) \ private:\ type name##_;\ public:\ const type& get_##name(){return name##_;}\ void set_##name(const type& val) { name##_ = val; } #define GEN_ENUM_FIELD(r,data,elem) BOOST_PP_CAT(FIELD_,BOOST_PP_SEQ_ELEM(1,elem)), #define DECLARE(type, name) DB_TOFIELD(type, name) #define GEN_FIELD_DECL(r, data, elem) DECLARE(BOOST_PP_SEQ_ELEM(0,elem),BOOST

Unroll loop at compile time

旧城冷巷雨未停 提交于 2019-12-02 12:09:57
问题 I want to write a load of lines into a C++ file of the form foo(i) for i = 0,1, ... , n , is there a way of doing this at compile time? I want to do this because I've got a templated class: template <int X> class MyClass{ ... } and I want to test it for lots of different values of "X" with something like: for (int i = 0; i < n; i++) { MyClass<i> bar; bar.method() } This doesn't work as it wants the value passed as the template value to be determined at compile time. I could write out the

How to write a c++ assert macro with a varying number of informational arguments?

青春壹個敷衍的年華 提交于 2019-12-02 00:53:49
问题 I am trying to write a macro dbgassert similar to the standard assert . In addition to what assert does, I want to dbgassert print an arbitrary number of additional parameters (containing debugging information). What I have so far is listed below, which is adapted from this SO answer. But I am having issue in my code with either variadic templates or macros. If I use at least one additional argument (the OK line), then dbgassert works as expected. But if I give no additional argument, then

How to write a c++ assert macro with a varying number of informational arguments?

本秂侑毒 提交于 2019-12-01 21:00:49
I am trying to write a macro dbgassert similar to the standard assert . In addition to what assert does, I want to dbgassert print an arbitrary number of additional parameters (containing debugging information). What I have so far is listed below, which is adapted from this SO answer . But I am having issue in my code with either variadic templates or macros. If I use at least one additional argument (the OK line), then dbgassert works as expected. But if I give no additional argument, then compilation fails (the problem line). I have some experience with variadic template programming (like

A group of variadic macros

萝らか妹 提交于 2019-12-01 19:05:40
I would like to have a group of variable number of arguments passed into a macro. I have following macros which is incorrect: #define M_NARGS(...) M_NARGS_(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) #define M_NARGS_(_10, _9, _8, _7, _6, _5, _4, _3, _2, _1, N, ...) N #define M_CONC(A, B) M_CONC_(A, B) #define M_CONC_(A, B) A##B #define M_ID(...) __VA_ARGS__ #define M_LEFT(L, R) L #define M_RIGHT(L, R) R #define M_FOR_EACH(ACTN, ...) M_CONC(M_FOR_EACH_, M_NARGS(__VA_ARGS__)) (ACTN, __VA_ARGS__) #define M_FOR_EACH_0(ACTN, E) E #define M_FOR_EACH_1(ACTN, E) ACTN(E) #define M_FOR_EACH_2(ACTN, E

C Preprocessor to split “int x” into int & x

我与影子孤独终老i 提交于 2019-12-01 05:16:50
问题 I need to be able to get the following: #define MY_MACRO(PARAM1,PARAM2) \ MY_OTHER_MACRO(TYPENAME_OF(PARAM1),PARAMNAME_OF(PARAM1));\ MY_OTHER_MACRO(TYPENAME_OF(PARAM2),PARAMNAME_OF(PARAM2));\ to cause MY_MACRO(int x,char *z) to compile as MY_OTHER_MACRO(int,x); MY_OTHER_MACRO(char*,z); or it would not be the end of the world if it compiled as: MY_OTHER_MACRO(int,x); MY_OTHER_MACRO(char,*z); or even this would be ok too: (i can code MY_OTHER_MACRO to work with either result) MY_OTHER_MACRO(int