Convert macro to a function but cannot concatenate inputs using std::stringstream

45 Views Asked by At

I currently have a macro:

#define MY_MACRO(cond, msg)                    \
    do                                         \
        {                                      \
            if (!(cond))                       \
            {                                  \
                std::cout << msg << std::endl; \
                std::abort();                  \
            }                                  \
    } while(0)

it's used to check boolean conditions and output a message if they fail.

Here's basic usage:

int p = 7;
MY_MACRO(false, "test (" << p << ")");

I'd like to replace it with a function like this:

static inline void MY_MACRO(const bool cond, const std::stringstream& ss)
{
    if(cond == false)
    {
        std::cout << ss.str() << std::endl;
        std::abort();
    }
}

However, std::stringstream doesn't seem to replicate the previous behavior because I'm getting compiler errors where the second parameter is passed in:

<source>:39:30: error: invalid operands to binary expression ('const char[7]' and 'int')
   39 |     MY_MACRO(false, "test (" << p << ")");
      |                     ~~~~~~~~ ^  ~

Is there a simple way to achieve this?

1

There are 1 best solutions below

0
TheNomad On BEST ANSWER

Alright, so a short POC based on our short chat would be this:

#include <iostream>

#define STRINGIFY(text) #text
#define TO_STRING(text) STRINGIFY(text)

#define MY_MACRO(cond, msg)                    \
    do                                         \
        {                                      \
            if (!(cond))                       \
            {                                  \
                std::cout << msg << std::endl; \
                WhatsAppMsg(TO_STRING(msg));  \
            }                                  \
    } while(0)

    static void WhatsAppMsg(const std::string str)
    {
        // add your WA or Telegram API call here after string sanitization by removing unwanted characters
        std::cout << str << std::endl;
    }

    int main()
    {
        int p = 7;
        MY_MACRO(false, "test (" << p << ")");

        return 0;
    }

The output is this:

ASM generation compiler returned: 0
Execution build compiler returned: 0
Program returned: 0
test (7)
"test (" << p << ")"

Just remember to cleanup the stringified quotes, which should be easier now since it's a standard string.

Of course, while this has least regression impact, if you'll do an external webservice call, then all kinds of crazy things can happen (such as network, certificate or server errors) so an exception can still be triggered; even if it doesn't, you should still be able to handle it as a regular error.

Also consider to not track any error from inside the messaging function with your macro to not end up in a vicious loop.

Anyway, this should get you started and in the right direction with what we discussed.