1

I'd like to create a C++ macro function to debug, and I'd like it to work like this:

int main(){
    int a = 3, b = 5, c = 7;
    string s = "<";

    print(a,s,b);
    print(a,s,b,s,c);
}

OUTPUT:
3 < 5
3 < 5 < 7

I've read a lot about variadic macros but anything I tried to code wouldnt work at all.

I thought about using lambda but didn't come up with algorithm to do it.

I need it like 1 line of code, cos it's just for debugging and more than that I could create a more complex function, but I guess this must be possible...

3
  • A macro cannot involve a runtime type such as std::string. Lambdas are a runtime thing too. Macros are for preprocessing, prior to any compilation, leave alone runtime. Commented Jul 31, 2016 at 20:27
  • what about char* ? or words that are not string, for example print(abc) where abc can be treated like #abc Commented Jul 31, 2016 at 20:29
  • If abc can be treated like #abc then it is something from the preprocessor. char* cannot do this either. int cannot be accessed form the preprocessor either. You could write some analyzer program to figure out the values of variables at a certain period of time within the execution of the program or just use a debugger or something that works at runtime. The C preprocessor has its limitations. m4 is a nice alternative that might come in handy here. Commented Jul 31, 2016 at 20:32

3 Answers 3

2

If you agree to replace the separator with '<<' (instead of ',') then the macro is very easy to define (note however that print is not a good name for a macro, that's why I renamed it appropriately):

#include <iostream>
#include <string>

#ifdef DEBUG
#define DEBUG_PRINT(x) std::cout << x << std::endl
#else
#define DEBUG_PRINT(x)
#endif

int main(){
    int a = 3, b = 5, c = 7;
    std::string s = "<";

    std::cout << "START" << std::endl;

    DEBUG_PRINT(a << s << b);
    DEBUG_PRINT(a << s << b << s << c);

    std::cout << "END" << std::endl;
    return 0;
}

Output:

$ g++ -DDEBUG main.cpp && ./a.out
START
3<5
3<5<7
END

$ g++ main.cpp && ./a.out
START
END
Sign up to request clarification or add additional context in comments.

Comments

2

You may use variadic template instead of MACRO:

template <typename ... Ts>
void print(Ts&&... args)
{
    int dummy[] = {0, ((std::cout << args), 0)...};
    static_cast<void>(dummy); // avoid warning for unused variable
    std::cout << std::endl;
}

or in c++17

template <typename ... Ts>
void print(Ts&&... args)
{
    (std::cout << ... << args) << std::endl;
}

Comments

1

I almost achieved what I wanted (with 2 lines of code):

#define print(args...) {db,args; cerr<<endl;}
struct dbg{template<typename T> dbg& operator , (const T& v){cerr<<v<<" "; return *this; }} db;

now I can just print(1,2,"asjd") and it works fine

3 Comments

You can even declare and define the struct inside the block since C++11 (and so remove the global).
you mean I can declare the struct inside de macro? how?
In fact you can declare local struct inside function, but NOT template method, so I was wrong. :/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.