Is there anyway to write the following as a C++ macro?
#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.
How to define a C macro that uses another macro?
The argument must be expanded by the macro:
#define TRIG_INDEX 200
#define PATH_TARGET(x) some.path.to.target##x
#define PATH(target_p) PATH_TARGET(target_p)
What does #x inside a C macro mean?
In this context (applied to a parameter reference in a macro definition), the pound sign means to expand this parameter to the literal text of the argument that was passed to the macro.
In this case, if you call PRINT(5)
the macro expansion will be printf("5" "%d\n", 5);
which will print 5 5
; not very useful; however if you call PRINT(5+5)
the macro expansion will be printf("5+5" "%d\n", 5+5);
which will print 5+5 10
, a little less trivial.
This very example is explained in this tutorial on the C preprocessor (which, incidentally, is the first Google hit for c macro pound sign).
Writing a C Macro
#define foo(x,i) (((x) & (3<<i)) == (3<<i)) ? ((x) - (3 << i)) : (x)
#define clear_11(x) foo(foo(foo(foo(foo(foo(foo(foo(foo(x,8),7),6),5),4),3),2),1),0)
This will do the job. However the expansion is quite big and compilation may take a while. So do not try this at work ;)
Can a C macro definition refer to other macros?
Short answer yes. You can nest defines and macros like that - as many levels as you want as long as it isn't recursive.
How to define a c macro with multiple statement
This is an appropriate time to use the do { ... } while (0)
idiom.
This is also an appropriate time to use variadic macro arguments.
#define FLUSH_PRINTF(...) \
do { \
printf(__VA_ARGS__); \
fflush(stdout); \
} while (0)
You could also do this with a wrapper function, but it would be more typing, because of the extra boilerplate involved with using vprintf
.
#include <stdarg.h>
#include <stdio.h>
/* optional: */ static inline
void
flush_printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
fflush(stdout);
}
How to create a C single-line comment macro
It doesn't work because the language specification doesn't allow it. In effect, comment removal happens before macro replacement. Once comments have been removed, //
is not a valid token (like the error message says). It can't be generated by macro replacement, and it no longer means "comment".
This is "Translation phases" in the standard. The section numbering differs, but all of C89, C99 and C11 define in phase 3:
Each comment is replaced by one space character.
and then in phase 4:
macro invocations are expanded
Using and returning output in C macro
This is relatively complicated code, there is not much reason to have it in a macro. Make it inline
(C99) or static
(C89) or both if you really want to place it in a header file. With any reasonable compiler this then should result in the same efficiency as a macro.
Related Topics
What's Time Complexity of This Algorithm for Finding All Combinations
Virtual Dispatch Implementation Details
C++11 Is_Same Type Trait for Templates
Cygwin Make Bash Command Not Found
"Apientry _Twinmain" and "Winapi Winmain" Difference
C++ Stl: Array VS Vector: Raw Element Accessing Performance
Why Not Just Use Random_Device
How Can It Be Useful to Overload the "Function Call" Operator
How Much Overhead Is There When Creating a Thread
How to Use Qt Without Qmake or Qt Creator
What's an Expression and Expression Statement in C++
Link Error "Undefined Reference to '_Gxx_Personality_V0'" and G++
Do Polymorphism or Conditionals Promote Better Design
How to Use a Std::Valarray to Store/Manipulate a Contiguous 2D Array