Is there anyway to write the following as a C++ macro? - c++

my_macro << 1 << "hello world" << blah->getValue() << std::endl;
should expand into:
std::ostringstream oss;
oss << 1 << "hello world" << blah->getValue() << std::endl;
ThreadSafeLogging(oss.str());

#define my_macro my_stream()
class my_stream: public std::ostringstream {
public:
my_stream() {}
~my_stream() {
ThreadSafeLogging(this->str());
}
};
int main() {
my_macro << 1 << "hello world" << std::endl;
}
A temporary of type my_stream is created, which is a subclass of ostringstream. All operations to that temporary work as they would on an ostringstream.
When the statement ends (ie. right after the semicolon on the whole printing operation in main()), the temporary object goes out of scope and is destroyed. The my_stream destructor calls ThreadSafeLogging with the data "collected" previously.
Tested (g++).
Thanks/credits to dingo for pointing out how to simplify the whole thing, so I don't need the overloaded operator<<. Too bad upvotes can't be shared.

Couldn't you just derive from ostream and provide your own thread safe implementation? Then you could just do
myCOutObject << 1 << "hello world" << blah->getValue() << std::endl;
And get the exact same functionality without macros and using C++ properly?

No. The problem is that without using function syntax, a macro is limited to only being replaced where it is.
But if you were willing to use function syntax, you can then replace stuff both before and after the args.
my_macro(1 << "hello world" << blah->getValue() << std::endl);
You could by defining MyMacro as:
#define my_macro(args) std::ostreamstring oss; \
oss << args; \
ThreadSafeLogging(oss.str());

Take a look at google-glog, they do this using a temporary object instanciated with a
LOG(INFO) << "log whatever" << 1;
and they also have other interesting macros such as LOG_IF et al.

Considering you have these lines included somewhere in your code, yes it is possible
#include <iostream>
#include <sstream>
__LINE__ macro is defined by all standart compilers.
So we can use it to generate a variable name wich is different each time you use the macro :)
Here is a new version that is seen as a one-statement instruction only:
(EDITED)
#define Var_(Name, Index) Name##Index
#define Var(Name, Index) Var_(Name, Index)
#define my_macro \
for (struct { int x; std::ostringstream oss; } Var(s, __LINE__) = { 0 }; \
Var(s, __LINE__).x<2; ++Var(s, __LINE__).x) \
if (Var(s, __LINE__).x==1) ThreadSafeLogging(Var(s, __LINE__).oss.str()); \
else Var(s, __LINE__).oss
// So you can use it like this
int main()
{
if (4 != 2)
my_macro << 4 << " hello " << std::endl;
my_macro << 2 << " world !" << std::endl;
}
Developper probably won't need to use this macro twice on same line becasue of simplicity of operator <<. But in case you need this, you can switch the use of __LINE__ by __COUNTER__ (which is non standard!). Thanks to Quuxplusone for this tip

Here's another nasty trick I saw somewhere else. It has a significant disadvantage compared to my other answer: you can't use it twice in the same scope because it declares a variable. However, it may still be interesting for other cases where you want to have somemacro foo run something after foo.
#define my_macro \
std::ostringstream oss; \
for (int x=0; x<2; ++x) \
if (x==1) ThreadSafeLogging(oss.str()); \
else oss
int main() {
my_macro << 1 << "hello world" << std::endl;
}

The logging setup I have is quite similar:
bool ShouldLog(const char* file, size_t line, Priority prio);
class LoggerOutput : public std::stringstream {
public:
LoggerOutput(const char* file, size_t line, Priority prio)
: prio(prio)
{
Prefix(file, line, prio);
}
void Prefix(const char* file, size_t line, Priority prio);
~LoggerOutput() {
Flush();
}
void Flush();
private:
Priority prio;
};
#define LOG(Prio) if (!Logging::ShouldLog(__FILE__, __LINE__, Prio)) {} else Logging::LoggerOutput(__FILE__, __LINE__, Prio)
If your logging is disabled, the ostream is never created and little overhead exists. You can configure logging on file name & line number(s) or priority levels. The ShouldLog function can change between invocations, so you could throttle or limit output. The log output uses two functions to modify itself, Prefix that adds a "file:line: (PRIO) " prefix to the line, and Flush() which both flushes it to the log output as a single command and adds a newline to it. In my implementation it always does, but you can make that conditional if one is not already there.

Related

How to implement a logging macro with automatic newline in C++

In the C++ library glog (Google logging module) there is a nice interface where you can write
LOG(INFO) << "abc " << my_var;
and at runtime it prints something like abc 5\n at runtime (if my_var was 5) where it automatically terminated with a newline.
This is much superior to having to always terminate with std::endl as in
std::cout << "abc " << my_var << std::endl;
What is the simpliest way (code + macros) do I need to replicate this effect in my code?
I think the idea is to return a temp wrapper object:
#include <iostream>
struct Log
{
~Log(void) { ::std::cout << ::std::endl; }
};
template<typename T> Log &&
operator <<(Log && wrap, T const & whatever)
{
::std::cout << whatever;
return ::std::move(wrap);
}
int main()
{
Log() << "whatever";
Log() << "more";
return 0;
}
online compiler
Note that the macro can be used here to execute conditional branching in the beginning of logging. That is skip logging if severity level is low.
#define LOG(level) \
if(g_log_lelevel <= level) Log()

Accessing variable values within a macro

Some time ago, I made this beautiful assert macro for c and c++ programs
#define ASSERT(truthy, message) \
if (!(truthy)) \
{\
cout << message << " on line " << __LINE__ << " in file " << __FILE__ << ". Check was " << #truthy << endl;\
}
Scatter ASSERT calls throughout your code, and it will warn you whenever the truthy value is not truthy! Very handy during development to remind you of potential mistakes.
ex
ASSERT(filesFound > 0, "Couldn't find any files, check your path!");
When filesFound is 0, the macro will print out
Couldn't find any files, check your path! on line 27 in file
openFiles.c. Check was filesFound > 0
Now what I want it to print, to give me even more relevant information, is the value of any variables passed into the truthy parameter. Like this
Couldn't find any files, check your path! on line 27 in file
openFiles.c. Check was filesFound > 0, filesFound is 0
This seems lisp-like territory, I wonder, is there any black magic c preprocessing that I can use to evaluate variables and functions to their values, without evaluating the truthy statement?
I assume to be disappointed.
An alternative solution which I've always used is to support varargs in the macro and then force the assert user to specify the relevant message / variables - it's a little bit of extra work each time, but on the plus side you can get exactly the formatting that you want and include information not available in the "truthy" bit, e.g:
#define ASSERT(truthy, message, ...) \
if (!(truthy)) \
{\
MyAssertHandler(__LINE__, __FILE__, #truthy, message, ##__VA_ARGS__);
}
Then you're handler is just a fairly standard var-arg function that can use e.g. vsnprintf to generate the message and output it, e.g. off the top of my head:
void MyAssertHandler(int line, const char* file, const char* expressionStr, const char* format, ...)
{
// Note: You probably want to use vsnprintf instead to first generate
// the message and then add extra info (line, filename, etc.) to
// the actual output
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
// Log to bug database, DebugBreak() if a debugger is attached, etc.
}
usage:
ASSERT(IsBlah(), "BlahBlah: x = %.2f, name = %s", GetX(), GetName());
I cannot imagine a way to do it... except by passing another parameter
#define ASSERT_PARAM(truthy, message, param) \
if (!(truthy)) \
{\
cout << message << " on line " << __LINE__ << " in file " << __FILE__ << ". Check was " << #truthy << ", value was " << param << endl;\
}
You would use it that way:
ASSERT_PARAM(filesFound > 0, "Couldn't find any files, check your path!", filesFound);
getting:
Couldn't find any files, check your path! on line 27 in file openFiles.c. Check was filesFound > 0, value was 0
What you are trying to do sounds very complicated. I'm afraid in C++ it's not possible.
Technically what you are evaluating is a bool expression so you can pass it to a parser whenever the assertion fails. The parser then will build the expression tree, get the leaves (elements of the expression) and return them. The returned values then should be printed out. To do that you will need support for reflection which is actually not supported in C++ AFAIK.
Maybe not the dream solution, but you can pass whole statements to a macro.
#define ASSERT(trusty, action) if (!trusty) { action }
ASSERT(trusty, cout << a << b;)
ASSERT(trusty, printf("%d, %f\n", a, b);)
I think you can split up the truthy Expression like they do it in the first answer here and then you can probably print the individual values. But I'm not sure if it actually works.
The printing could then be resulved using a variadic template function
Perhaps you could compromise and only allow 2 variables and 1 operator in the assertion expression? If so, you could make an ad hoc solution like this:
#include <iostream>
#include <string>
#define STRINGIFY(x) #x
#define BIN_ASSERT(obj1, op, obj2, msg) \
if(!(obj1 op obj2)) \
{ \
std::cout << msg << " on line " << __LINE__ \
<< " in file " << __FILE__ \
<< "." << std::endl \
<< "Check was " \
<< STRINGIFY(obj1) STRINGIFY(op) STRINGIFY(obj2) \
<< "." << std::endl \
<< "Operator " << #obj1 << ": " << obj1 \
<< "." << std::endl \
<< "Operator " << #obj2 << ": " << obj2 \
<< "." << std::endl; \
}
int main (void)
{
int x = 2;
int y = 3;
std::string s1 = "hello";
std::string s2 = "world";
BIN_ASSERT(1, +, -1, "Value zero"); std::cout << std::endl;
BIN_ASSERT(x, ==, y, "Numbers not equal"); std::cout << std::endl;
BIN_ASSERT(s1, ==, s2, "Strings not equal"); std::cout << std::endl;
}
Output:
Value zero on line 30 in file test.c.
Check was 1+-1.
Operator 1: 1.
Operator -1: -1.
Numbers not equal on line 31 in file test.c.
Check was x==y.
Operator x: 2.
Operator y: 3.
Strings not equal on line 32 in file test.c.
Check was s1==s2.
Operator s1: hello.
Operator s2: world.
I wonder if having the macro take a message is really that useful. A failed assertion is a message to the developer that there is a bug in the code that caused an exceptional behaviour or put the program in an unacceptable state. The user has less to do with it (if they even have access to the source code).
The code below defines an ASSERT macro that takes a boolean expression, evaluates it and prints an informational message. The message contains a value that you've asked to inspect upon failing the assertion.
The macro, just like the standard assert() macro (in <cassert>) goes on to call abort() (from <cstdlib>) to cause an abnormal program termination. This is what you want, because the program entered a state in which it didn't know what more to do.
I'm using std::printf() here for brevity. You do whatever you want.
#include <cstdlib>
#include <cstdio>
#define ASSERT(value, inspect) \
if (!(value)) { \
std::printf("ASSERTION FAILED: '%s', %s is %d: %s#%s:%d\n", #value, \
#inspect, inspect, __func__, __FILE__, __LINE__); \
abort(); \
}
int foo() { return 42; }
int main()
{
// ...
ASSERT(foo() - 40 == 1, foo());
//...
}
Program run:
$ ./a.out
ASSERTION FAILED: 'foo() - 40 == 1', foo() is 42: main#prog.cc:16
Abort
It's not possible to do exactly what you ask for without adding more parameters to the macro. At some point you'll have to stop and realize that you're spending time on creating a text string that you do not want to see.
You need to build an expression 'grabber' / builder.
The macro would become something like:
#define ASSERT_PARAM(truthy, message, param) \
if (!(truthy)) \
{\
Grabber g;
g << #truthy; // grab expression as string
g % truthy; // grab expression and values
cout << message << " on line " << __LINE__ << " in file " << __FILE__ << ". Check was " << #truthy << ", value was " << param << endl;\
cout << g; \
}
What does Grabber do?
It is a bunch of crazy C++ that builds up an expression. It would overload every operator to 'grab' the params of the operator. Every operator returns a reference to the grabber, so it can grab the next operator. ie
Grabber g;
g % filesFound > 0;
Since % (and * and /) have high precedence, the above parses like:
((g % filesFound) > 0)
If template<typename T> Grabber::operator%(T const & val) just records (or prints) the value passed in (ie filesFound), and - importantly - returns itself (g) so that it becomes part of the next expression: ie it becomes g > 0. Causing template<typename T> Grabber::operator>(T const & val) to be called, and > 0 to be recorded.
Then cout << g can spew out everything grabbed.
As mentioned above "It is possible — the Catch library does it. But it’s hellishly difficult".
P.S. you should wrap your macro in a do ... while 0 like this:
#define ASSERT_PARAM(truthy, message, param) \
do \
{ \
if (!(truthy)) \
{\
cout << message << " on line " << __LINE__ << " in file " << __FILE__ << ". Check was " << #truthy << ", value was " << param << endl;\
cout << g; \
} \
} while (0)
What you have currently means that this is valid code:
ASSERT(foo != 0)
else
{
}
And this is NOT valid code:
if (foo != nullptr)
ASSERT(foo->bar != nullptr);
else
x = 10;
Surprisingly, I solved a similar problem before, but I'm not sure if it could help you in this case.
The original solution was proposed by Andrei Alexandrescu in the article Enhancing Assertions, and with no question, relying on some macro tricks.
This amazing facility can be used as the following:
string s1, s2;
...
SMART_ASSERT(s1.empty() && s2.empty())(s1)(s2);
And if something goes wrong, the message would be displayed
Assertion failed in matrix.cpp: 879412:
Expression: 's1.empty() && s2.empty()'
Values: s1 = "Wake up, Neo"
s2 = "It's time to reload."
Be noted that, the SMART_ASSERT can capture infinite variables, theoretically.
For implementation details, please check out the article.

multiple threads writing to std::cout or std::cerr

I have OpenMP threads that write to the console via cout and cerr. This of course is not safe, since output can be interleaved. I could do something like
#pragma omp critical(cerr)
{
cerr << "my variable: " << variable << endl;
}
It would be nicer if could replace cerr with a thread-safe version, similar to the approach explained in the valgrind DRD manual (http://valgrind.org/docs/manual/drd-manual.html#drd-manual.effective-use) which involves deriving a class from std::ostreambuf. Ideally in the end I would just replace cerr with my own threaded cerr, e.g. simply:
tcerr << "my variable: " << variable << endl;
Such a class could print to the console as soon as it encounters an "endl". I do not mind if lines from different threads are interleaved, but each line should come only from one thread.
I do not really understand how all this streaming in C++ works, it is too complicated. Has anybody such a class or can show me how to create such a class for that purpose?
As others pointed out, in C++11, std::cout is thread-safe.
However if you use it like
std::cout << 1 << 2 << 3;
with different threads, the output can still be interleaved, since every << is a new function call which can be preceeded by any function call on another thread.
To avoid interleaving without a #pragma omp critical - which would lock everything - you can do the following:
std::stringstream stream; // #include <sstream> for this
stream << 1 << 2 << 3;
std::cout << stream.str();
The three calls writing 123 to the stream are happening in only one thread to a local, non-shared object, therefore aren't affected by any other threads. Then, there is only one call to the shared output stream std::cout, where the order of items 123 is already fixed, therefore won't get messed up.
You can use an approach similar to a string builder. Create a non-template class that:
offers templated operator<< for insertion into this object
internally builds into a std::ostringstream
dumps the contents on destruction
Rough approach:
class AtomicWriter {
std::ostringstream st;
public:
template <typename T>
AtomicWriter& operator<<(T const& t) {
st << t;
return *this;
}
~AtomicWriter() {
std::string s = st.str();
std::cerr << s;
//fprintf(stderr,"%s", s.c_str());
// write(2,s.c_str(),s.size());
}
};
Use as:
AtomicWriter() << "my variable: " << variable << "\n";
Or in more complex scenarios:
{
AtomicWriter w;
w << "my variables:";
for (auto & v : vars) {
w << ' ' << v;
}
} // now it dumps
You will need to add more overloads if you want manipulators, you can use write better than fprintf for the atomic write in the destructor, or std::cerr, you can generalize so that the destination is passed to the constructor (std::ostream/file descriptor/FILE*),
I don't have enough reputation to post a comment, but I wanted to post my addition to the AtomicWriter class to support std::endl and allow for other streams to be used besides std::cout. Here it is:
class AtomicWriter {
std::ostringstream st;
std::ostream &stream;
public:
AtomicWriter(std::ostream &s=std::cout):stream(s) { }
template <typename T>
AtomicWriter& operator<<(T const& t) {
st << t;
return *this;
}
AtomicWriter& operator<<( std::ostream&(*f)(std::ostream&) ) {
st << f;
return *this;
}
~AtomicWriter() { stream << st.str(); }
};
Put the following code in header file atomic_stream_macro.h
#ifndef atomic_stream_macro_h
#define atomic_stream_macro_h
#include <mutex>
/************************************************************************/
/************************************************************************/
extern std::mutex print_mutex;
#define PRINT_MSG(out,msg) \
{ \
std::unique_lock<std::mutex> lock (print_mutex); \
\
out << __FILE__ << "(" << __LINE__ << ")" << ": " \
<< msg << std::endl; \
}
/************************************************************************/
/************************************************************************/
#endif
Now the macro can be used from a file as follows.
#include <atomic_stream_macro.h>
#include <iostream>
int foo (void)
{
PRINT_MSG (std::cout, "Some " << "Text " << "Here ");
}
Finally, in the main.cxx, declare the mutex.
#include <mutex>
std::mutex print_mutex;
int main (void)
{
// launch threads from here
}
You could do it by inheriting std::basic_streambuf, and override the correct functions to make it threadsafe. Then use this class for your stream objects.

Need a macro to create a std::string from a std::ostringstream and a << arg list

I want to write a macro that takes as its only argument a list of std::ostream& operator<< concatenated objects and passes the consolidated string as a single std::string object to a function. The ability to pass the consolidated string to a function is key; in the example below I am aware that the example itself could be rewritten to work simply by defining the macro to ERR_MSG(inputs) std::cout << "ERROR: " << inputs, but sending the output to std::cout is not the goal, it's just the test objective I chose for the example.
I'm using GCC 4.1.2 (Red Hat 4.1.2-52) and upgrading it is not an option. Here's a very boiled-down version of what I've tried:
#include <sstream>
#include <iostream>
#define ERR_MSG(inputs) errMsg(std::ostringstream().str()) // 1
#define ERR_MSG(inputs) errMsg((std::ostringstream()<<inputs).str()) // 2
<aReturnType> errMsg(const std::string& msg) // use with 1 & 2
{
std::cout << "\nERROR: " << msg << "\n\n";
return <someObjectCreatedBasedOnTheInput>;
}
#define ERR_MSG(inputs) errMsg(std::ostringstream()<<inputs) // 3
<aReturnType> errMsg(const std::ostringstream& msg) // use with 3
{
std::cout << "\nERROR: " << msg.str() << "\n\n";
return <someObjectCreatedBasedOnTheInput>;
}
int main()
{
ERR_MSG("A number: " << 24 << ", a char: " << 'c' << ", that's all!");
}
Macro #1 compiles, but of course prints nothing but "" for the message. Neither macros 2 & 3 compile, with the following errors:
#define ERR_MSG(inputs) errMsg((std::ostringstream()<<inputs).str()) // 2
error: ‘struct std::basic_ostream<char, std::char_traits<char> >’ has no member named ‘str’
#define ERR_MSG(inputs) errMsg(std::ostringstream()<<inputs) // 3
no matching function for call to ‘errMsg(std::basic_ostream<char, std::char_traits<char> >&)’
note: candidates are: char* errMsg(const std::string&)
note: char* errMsg(const std::ostringstream&)
I am not interested in how I could rewrite this without macros; I can do that quite easily myself.
=== UPDATE: ===
I forgot to mention that in its real use case, the function called by the macro returns an object that may be used by the caller of the macro. That invalidates any macro implementations that cannot be implemented in a single expression whose result is the returned type of the function called by the macro. The "do nothing" implementation of the macro (for release builds) will simply pass an empty std::string to the function regardless of what the "inputs" are. Sorry for not mentioning that earlier.
Your current problem is that all of the various operator<< functions return an ostream&, not an ostringstream&. You can solve that with a simple cast:
#define ERR_MSG(inputs) errMsg((static_cast<std::ostringstream&>(std::ostringstream().flush() << inputs)).str())
The flush is needed because std::ostringstream() is a temporary. Therefore, you can't call functions on it that take an lvalue reference (ie: std::ostream&). Functions like most operator<< variants. All the flush call does is return the this pointer as an lvalue reference.
If you are willing to use some GCC extension, you could declare an actual ostringstream inside the macro in a block, so that the .str() method can be used without casting:
#define ERR_MSG(inputs) \
do { std::ostringstream _s_; _s_<<inputs;errMsg(_s_.str()); } while(false)
Demo: http://ideone.com/clone/y56lc
Use do { } while (false) idiom to make a few lines macro.
#define ERR_MSG(inputs) \
do { \
std::ostringstream osERR_MSG; \
osERR_MSG << inputs; \
errMsg(osERR_MSG.str()); \
} while (false)
int main() {
if (1) ERR_MSG("A number: " << 24 << ", a char: " << 'c' << ", that's all!");
else return 0;
}
The reason I made such strange name osERR_MSG is to avoid as much as possible cases like this:
int osERR_MSG = 7;
ERR_MSG(osERR_MSG);
#include <sstream>
#include <iostream>
#define ERR_MSG(inputs) errMsg(std::ostringstream().flush()<<inputs)
int errMsg(std::ostream& os)
{
std::ostringstream& oss(static_cast<std::ostringstream&>(os));
const std::string& str(oss.str());
std::cout << "\nERROR: " << str << "\n\n";
return str.length();
}
int main()
{
int i = ERR_MSG("A number: " << 24 << ", a char: " << 'c' << ", that's all!");
std::cout << i << "\n";
}
I'd not create an std::ostringstream but rather have a function called from the destructor of a class derived from std::ostream. Here is an example of this approach:
#include <sstream>
#include <iostream>
void someFunction(std::string const& value)
{
std::cout << "someFunction(" << value << ")\n";
}
void method(std::string const& value)
{
std::cout << "method(" << value << ")\n";
}
class FunctionStream
: private virtual std::stringbuf
, public std::ostream
{
public:
FunctionStream()
: std::ostream(this)
, d_function(&method)
{
}
FunctionStream(void (*function)(std::string const&))
: std::ostream(this)
, d_function(function)
{
}
~FunctionStream()
{
this->d_function(this->str());
}
private:
void (*d_function)(std::string const&);
};
int main(int ac, char* av[])
{
FunctionStream() << "Hello, world: " << ac;
FunctionStream(&someFunction) << "Goodbye, world: " << ac;
}
The example use doesn't use a macro but this can be wrapped easily around the above use of FunctionStream(). Note, that in a macro you probably want to make sure that the type seen by the user of the macro is of type std::ostream& rather than a temporary type so it can be used directly with user defined output operators. To this end you should have an insertion for one of the types directly supported by std::ostream which doesn't have any effect but returns an std::ostream&, for example:
#define SomeMacro(output) FunctionStream(&someFunction) << "" << output
Reinstating Nicol's answer as its the best so far:
Your current problem is that all of the various operator<< functions return an ostream&, not an ostringstream&. You can solve that with a simple cast:
#define ERR_MSG(inputs) errMsg((static_cast<std::ostringstream&>(std::ostringstream().flush() << inputs)).str())
Of course, this still has the problem (like all the answers here) that something like
ERR_MSG(x ? "x is true" : "x is false")
will misbehave in an odd and confusing manner.

Writing a macro for logging

I'm writing a logging class at the moment. The Logger works with streams and also prints the object which is logging at the moment. Here is the macro:
#define OBJLOG(DL, what) DL <= this->Logger->getDebugLevel() ? *this->Logger << DL << "[" << this->Name << "]: "<< what << std::endl : this->Logger->doNothing();
The pseudo code Variant for better overview:
#define OBJLOG(debuglevel, what) debuglevel <= logger.debuglevel ? logger.log(what) : logger.doNothing()
Is there any way to get around the doNothing function call, like doing nothing at all?
#define OBJLOG(DL, what) do { if(DL <= this->Logger->getDebugLevel()) *this->Logger << DL << "[" << this->Name << "]: "<< what << std::endl; } while(0)
See Why use apparently meaningless do-while and if-else statements in macros? for an explanation. (The do {} while(0) isn't strictly necessary here, but I would prefer not to leak an ostream.)
Also, you should always wrap macro argument uses in parentheses, like:
#define OBJLOG(DL, what) do { if((DL) <= this->Logger->getDebugLevel()) *this->Logger << (DL) << "[" << this->Name << "]: "<< (what) << std::endl; } while(0)
Finally, you should move this code into a function and call that in your macro (if you really insist on using a macro) to avoid evaluating your macro arguments more than once.
Have your logger.log() function return a boolean.
Connect your predicates with an and like this: debuglevel <= logger.debuglevel && logger.log
That should do the trick.
If you want an expression that does nothing, try (void)0.