I just encountered a DEBUG macro in C that I really like
#ifdef DEBUG_BUILD
# define DEBUG(x) fprintf(stderr, x)
#else
# define DEBUG(x) do {} while (0)
#endif
I'm guessing a C++ analogue would be :-
#ifdef DEBUG_BUILD
# define DEBUG(x) cerr << x
#else
# define DEBUG(x) do {} while (0)
#endif
Is the second code snippet analogous to the one in C?
Do you have any favorite C++ debug macros?
EDIT :
By "Debug Macros" I mean "macros that might come in handy while running a program in debug mode".
Is the second code snippet analogous to the one in C?
More or less. It's is more powerful, as you can include <<-separated values in the argument, so with a single argument you get something that would require a variable number of macro arguments in C. On the other hand, there is a slim chance that people will abuse it by including a semicolon in the argument. Or even encounter mistakes due to a forgotten semicolon after the call. So I'd include this in a do block:
#define DEBUG(x) do { std::cerr << x; } while (0)
Do you have any favourite C++ debug macros?
I like the one above and use it quite often. My no-op usually just reads
#define DEBUG(x)
which has the same effect for optimizing compilers. Although the comment by #Tony D below is correct: this can leave some syntax errors undetected.
I sometimes include a run-time check as well, thus providing some form of a debug flag. As #Tony D reminded me, having an endl in there is often useful as well.
#define DEBUG(x) do { \
if (debugging_enabled) { std::cerr << x << std::endl; } \
} while (0)
Sometimes I also want to print the expression:
#define DEBUG2(x) do { std::cerr << #x << ": " << x << std::endl; } while (0)
In some macros, I like to include __FILE__, __LINE__ or __func__, but these are more often assertions and not simple debug macros.
Here's my favorite
#ifdef DEBUG
#define D(x) x
#else
#define D(x)
#endif
It's super handy and makes for clean (and importantly, fast in release mode!!) code.
Lots of #ifdef DEBUG_BUILD blocks all over the place (to filter out debug related blocks of code) is pretty ugly, but not so bad when you wrap a few lines with a D().
How to use:
D(cerr << "oopsie";)
If that's still too ugly/weird/long for you,
#ifdef DEBUG
#define DEBUG_STDERR(x) (std::cerr << (x))
#define DEBUG_STDOUT(x) (std::cout << (x))
//... etc
#else
#define DEBUG_STDERR(x)
#define DEBUG_STDOUT(x)
//... etc
#endif
(I suggest not using using namespace std; though maybe using std::cout; using std::cerr; could be a good idea)
Note that you might want to do more things than just print to stderr when you are thinking about "debugging". Get creative, and you can build constructs that offer insight into the most complex interactions within your program, while allowing you to very quickly switch to building a super efficient version unencumbered by debug instrumentation.
For example in one of my recent projects I had a huge debug-only block which started with FILE* file = fopen("debug_graph.dot"); and proceeded to dump out a graphviz compatible graph in dot format to visualize large trees within my datastructures. What's even cooler is the OS X graphviz client will auto-read the file from disk when it changes, so the graph refreshes whenever the program is run!
I also particularly like to "extend" classes/structs with debug-only members and functions.
This opens up the possibility of implementing functionality and state that is there to help you track down bugs, and just like everything else that is wrapped in debug macros, is removed by switching a build parameter. A giant routine that painstakingly checks each corner case on every state update? Not a problem. Slap a D() around it. Once you see it works, remove -DDEBUG from the build script, i.e. build for release, and it's gone, ready to be re-enabled at a moment's notice for your unit-testing or what have you.
A large, somewhat complete example, to illustrate (a perhaps somewhat overzealous) use of this concept:
#ifdef DEBUG
# define D(x) x
#else
# define D(x)
#endif // DEBUG
#ifdef UNITTEST
# include <UnitTest++/UnitTest++.h>
# define U(x) x // same concept as D(x) macro.
# define N(x)
#else
# define U(x)
# define N(x) x // N(x) macro performs the opposite of U(x)
#endif
struct Component; // fwd decls
typedef std::list<Component> compList;
// represents a node in the graph. Components group GNs
// into manageable chunks (which turn into matrices which is why we want
// graph component partitioning: to minimize matrix size)
struct GraphNode {
U(Component* comp;) // this guy only exists in unit test build
std::vector<int> adj; // neighbor list: These are indices
// into the node_list buffer (used to be GN*)
uint64_t h_i; // heap index value
U(int helper;) // dangling variable for search algo to use (comp node idx)
// todo: use a more space-efficient neighbor container?
U(GraphNode(uint64_t i, Component* c, int first_edge):)
N(GraphNode(uint64_t i, int first_edge):)
h_i(i) {
U(comp = c;)
U(helper = -1;)
adj.push_back(first_edge);
}
U(GraphNode(uint64_t i, Component* c):)
N(GraphNode(uint64_t i):)
h_i(i)
{
U(comp=c;)
U(helper=-1;)
}
inline void add(int n) {
adj.push_back(n);
}
};
// A component is a ugraph component which represents a set of rows that
// can potentially be assembled into one wall.
struct Component {
#ifdef UNITTEST // is an actual real struct only when testing
int one_node; // any node! idx in node_list (used to be GN*)
Component* actual_component;
compList::iterator graph_components_iterator_for_myself; // must be init'd
// actual component refers to how merging causes a tree of comps to be
// made. This allows the determination of which component a particular
// given node belongs to a log-time operation rather than a linear one.
D(int count;) // how many nodes I (should) have
Component(): one_node(-1), actual_component(NULL) {
D(count = 0;)
}
#endif
};
#ifdef DEBUG
// a global pointer to the node list that makes it a little
// easier to reference it
std::vector<GraphNode> *node_list_ptr;
# ifdef UNITTEST
std::ostream& operator<<(std::ostream& os, const Component& c) {
os << "<s=" << c.count << ": 1_n=" << node_list_ptr->at(c.one_node).h_i;
if (c.actual_component) {
os << " ref=[" << *c.actual_component << "]";
}
os << ">";
return os;
}
# endif
#endif
Notice that for large blocks of code, I just use regular block #ifdef conditionals because that improves readability somewhat, as for large blocks the use of extremely short macros is more of a hindrance!
The reason why the N(x) macro must exist is to specify what to add when unit-testing is disabled.
In this part:
U(GraphNode(uint64_t i, Component* c, int first_edge):)
N(GraphNode(uint64_t i, int first_edge):)
It would be nice if we could say something like
GraphNode(uint64_t i, U(Component* c,) int first_edge):
But we cannot, because the comma is a part of preprocessor syntax. Omitting the comma produces invalid C++ syntax.
If you had some additional code for when not compiling for debug, you could use this type of corresponding inverse-debug macro.
Now this code might not be an example of "really good code" but it illustrates some of the things that you can accomplish with clever application of macros, which if you remain disciplined about, are not necessarily evil.
I came across this gem just now after wondering about the do{} while(0) stuff, and you really do want all that fanciness in these macros as well!
Hopefully my example can provide some insight into at least some of the clever things that can be done to improve your C++ code. It is really valuable to instrument code while you write it rather than to come back to do it when you don't understand what's happening. But it is always a balance that you must strike between making it robust and getting it done on time.
I like to think of additional debug build sanity checks as a different tool in the toolbox, similar to unit tests. In my opinion, they could be even more powerful, because rather than putting your sanity check logic in unit tests and isolating them from the implementation, if they are included in the implementation and can be conjured at will, then complete tests are not as necessary because you can simply enable the checks and run things as usual, in a pinch.
For question 1] Answer is yes. It will just print the message to standard error stream.
For question 2] There are many. My Fav is
#define LOG_ERR(...) fprintf(stderr, __VA_ARGS__)
which will allow one to include arbitrary number of variables to include in the debug message.
I like to use macros with __LINE__, __FILE__ as arguments to show where in the code the printout is from - it's not uncommon to print the same variable name in several places, so fprintf(stderr, "x=%d", x); won't mean much if you then add another one the same ten lines further down.
I've also used macros that override certain functions and store where it was called from (e.g. memory allocations), so that later on, I can figure out which one it was that leaked. For memory allocation, that's a little harder in C++, since you tend to use new/delete, and they can't easily be replaced, but other resources such as lock/unlock operations can be very useful to trace this way [of course, if you have a locking wrapper that uses construction/destruction like a good C++ programmer, you'd add it to the constructor to add file/line to the internal structure once you have acquired the lock, and you can see where it's held elsewhere when the you can't acquire it somewhere].
This is the log macro I am using currently:
#ifndef DEBUG
#define DEBUG 1 // set debug mode
#endif
#if DEBUG
#define log(...) {\
char str[100];\
sprintf(str, __VA_ARGS__);\
std::cout << "[" << __FILE__ << "][" << __FUNCTION__ << "][Line " << __LINE__ << "] " << str << std::endl;\
}
#else
#define log(...)
#endif
Usage:
log(">>> test...");
Output:
xxxx/proj.ios_mac/Classes/IntroScene.cpp][gotoNextScene][Line 58] >>> test...
… and as addendum to all responses:
Personally I never use macros like DEBUG to distinct debug from release code, instead I use NDEBUG which is must be defined for release builds to eliminate assert() calls (yes, I use assert() extensively). And if latter is not defined, then it is a debug build. Easy! So, actually there is no reason to introduce one more debug macro! (and handle possible cases when DEBUG and NDEBUG both are not defined).
This is my version, using a variadic template print function:
template<typename... ArgTypes>
inline void print(ArgTypes... args)
{
// trick to expand variadic argument pack without recursion
using expand_variadic_pack = int[];
// first zero is to prevent empty braced-init-list
// void() is to prevent overloaded operator, messing things up
// trick is to use the side effect of list-initializer to call a function
// on every argument.
// (void) is to suppress "statement has no effect" warnings
(void)expand_variadic_pack{0, ((cout << args), void(), 0)... };
}
#ifndef MYDEBUG
#define debug_print(...)
#else
#define debug_print(...) print(__VA_ARGS__)
#endif
The version I makes the debug_print a variadic template function which accepts a debug level which allows me to select what kind of output I want to output at runtime:
template<typename... ArgTypes>
inline void debug_print(debug::debug level, ArgTypes... args)
{
if(0 != (debug::level & level))
print(args...);
}
Note the print function crashes Visual Studio 2013 Preview (I haven't tested the RC). I have noticed it is faster (on Windows, where console output is slow) than my previous solution which used an ostream child class that overloaded operator<<.
You can also use a temporary stringstream inside print if you only want to call the real output function once (or write your own typesafe printf ;-))
I use the code below for logging. There are a few advantages:
I can turn them on/off at runtime.
I can compile out statements at a particular log level. For example, at the moment, I've unconditionally compiled in the KIMI_PRIVATE macro because I'm debugging something in the release build but since there is a lot of potentially secret sauce stuff being logged (lol), I compile it out of release builds.
This pattern has served me very well over the years. Note: although there is a global logMessage function, the code usually queues the log to a logging thread.
#define KIMI_LOG_INTERNAL(level,EXPR) \
if(kimi::Logger::loggingEnabled(level)) \
{ \
std::ostringstream os; \
os << EXPR; \
kimi::Logger::logMessage(level ,os.str()); \
} \
else (void) 0
#define KIMI_LOG(THELEVEL,EXPR) \
KIMI_LOG_INTERNAL(kimi::Logger::LEVEL_ ## THELEVEL,EXPR)
#define KIMI_ERROR(EXPR) KIMI_LOG(ERROR,EXPR)
#define KIMI_VERBOSE(EXPR) KIMI_LOG(VERBOSE,EXPR)
#define KIMI_TRACE(EXPR) KIMI_LOG(TRACE,EXPR)
#define KIMI_INFO(EXPR) KIMI_LOG(INFO,EXPR)
#define KIMI_PROFILE(EXPR) KIMI_LOG(TRACE,EXPR)
// Use KIMI_PRIVATE for sensitive tracing
//#if defined(_DEBUG)
# define KIMI_PRIVATE(EXPR) KIMI_LOG(PRIVATE,EXPR)
// #else
// # define KIMI_PRIVATE(EXPR) (void)0
// #endif
I use following micro,
#if DEBUG
#define LOGE2(x,y) std::cout << "ERRO : " << "[" << __FILE__ << "][" << __FUNCTION__ << "][Line " << __LINE__ << "] " << x <<":"<< y <<std::endl;
#define LOGI2(x,y) std::cout << "INFO : " << "[" << __FILE__ << "][" << __FUNCTION__ << "][Line " << __LINE__ << "] " << x <<":"<< y << std::endl;
#define LOGD2(x,y) std::cout << "DEBG : " << "[" << __FILE__ << "][" << __FUNCTION__ << "][Line " << __LINE__ << "] " << x <<":"<< y << std::endl;
#define LOGE(x) std::cout << "ERRO : " << "[" << __FILE__ << "][" << __FUNCTION__ << "][Line " << __LINE__ << "] " << x << std::endl;
#define LOGI(x) std::cout << "INFO : " << "[" << __FILE__ << "][" << __FUNCTION__ << "][Line " << __LINE__ << "] " << x << std::endl;
#define LOGD(x) std::cout << "DEBG : " << "[" << __FILE__ << "][" << __FUNCTION__ << "][Line " << __LINE__ << "] " << x << std::endl;
#else
#define LOGE2(x,y) NULL
#define LOGI2(x,y) NULL
#define LOGD2(x,y) NULL
#define LOGE(x) NULL
#define LOGI(x) NULL
#define LOGD(x) NULL
#endif
USE:
LOGE("ERROR.");
LOGE2("ERROR1","ERROR2");
As is clear from the other answers, there are many. There is one that I like which both allows for a variable number of arguments, prints the names of the arguments, and which includes a newline.
void debug_print() { std::cerr << std::endl; }
template <typename Head, typename... Tail>
void debug_print(Head H, Tail... T) {
std::cerr << ' ' << H;
debug_print(T...);
}
#ifdef DEBUGFLAG
# define DEBUG(...) std::cerr << "dbg (" << #__VA_ARGS__ << "):", \
debug_print(__VA_ARGS__)
#else
# define DEBUG(...) do {} while(0)
#endif
Much of the explanation is as in this answer, but I find that the additional templating simplifies it when I want to debug-print several variables on one line without having different macros.
Related
I'd like to implement a macro which does the following:
#define report(s) print(), throw std::runtime_error(s)
print() is a function that I always call to print some predefined stuff. s need to support:
report("abc"); // ok
report("abc"<<100); // == report("abc100")
Apart from whatever print() outputs, Nothing else should be printed. The exception will be caught by the caller and printed there.
I find it difficult to support << in the above macro.
P.S. report() is a macro already used every where in my code base and I just want to change its behaviour. Calls like report("abc"<<100); have to be supported. define it as a function and add ';' at the end doesn't look appropriate.
Perhaps the following (untested!) code might be inspirational
#define report(Log) do { std::ostringstream _os; \
_os << Log << std::flush; print(_os.str()); \
throw std::runtime(_os.str()); } while(0)
and you might use it as report("x=" << x);
BTW, you might even pass the source location using
#define report_at(Log,Fil,Lin) do { std::ostringstream _os; \
_os << Fil << ":" << Lin << ": " << Log << std::flush; \
print(_os.str()); \
throw std::runtime(_os.str()); } while(0)
(to lower probability of collision with _os you might even replace all its occurrences inside the brace with _os##Lin using preprocessor concatenation)
#define report_at_bis(Log,Fil,Lin) report_at(Log,Fil,Lin)
#define report(Log) report_at_bis(Log,__FILE__,__LINE__)
and this shows one of the cases where a macro is really useful.
Suppose I have two overloaded functions :
fun1(int)
fun1()
In this case how can I use #pragma startup directive to start my program's execution with fun1(int) ?
The syntax only contains the function name :
#pragma startup fun1 100
Is there any way by which I can make a choice between these two functions?
UPDATE:
compiler- turbo c/c++ 3.1 (sorry for an old compiler )
It is a Borland specific directive, still documented as well. It just lets you specify a function that runs before the main() function is entered. You normally use it for an initialization function. It is a small band-aid for the infamous "static initialization order fiasco" that C and C++ implementations suffer from. Not so sure it stops the bleeding, having to pick the priority number ought to get impractical when the program gets large.
Anyhoo, nothing you ought to use as a replacement of main(). Although I'd suspect you could make it work as long as you don't return from the function and call exit(). You can't use an argument of course, there's nothing meaningful that the CRT can pass. So overloads can't work either. Stick with main().
#joey-rohan, I dont have borland but have tried to provide some code below to demonstrate:
#pragma start requires a non parameterised function, the number after the function call is the priority of the function where 0 is the highest and 255 the lowest. The function should ideally (varies in some compilers) be defined prior to the #pragma call. Source: embarcadero
I have done a bit of scouting about and think that the solution to your dilemma would be to use a mixture of #define and #pragma to achieve what you would like to do. For example something like:
#include <iostream>
#define myvalue 100
#define usemyvalue 0
void fun1(int passedInValue)
{
// carry out function here
std::cout << "I was passed the value:" << passedInValue << std::endl;
}
void fun1(void)
{
std::cout << "in fun1(void)\n";
std::cout << "Use my value = " << usemyvalue<< std::endl;
if (usemyvalue==1)
{
std::cout << "Using fun1(int) with a value!\n";
fun1((int)myvalue); // remember to cast as an int here
}
else
{
//normal fun1()code here
std::cout << "No var passed!\n";
std::cout << "Running standard non parametrised code!\n";
}
}
#pragma start fun1 10
int main()
{
std::cout << "Hello World\n";
return 0;
}
I know this is not as elegant as I would wish, therefore its probably not as elegant as you would like either, however it does allow for the functionality you need, with minimal modification. Unfortunately i only have GCC available to test against on this machine and it does not seem to support #pragma start it does however support a differing way of achieving the same (as shown on C Language Constructors and Destructors with GCC
so here is some code for GCC which I could test to let you see how to achieve what you are asking (because I would hate to pst a methodology that cannot be proven):
#include <iostream>
#define myvalue 100
#define usemyvalue 1 // this is the control switch to determine which to use,
// if the value is 1 then will pass a variable, otherwise will use
// the fun1(void) function
void fun1 (void) __attribute__((constructor));
void fun1(int passedInValue)
{
// carry out function here
std::cout << "I was passed the value:" << passedInValue << std::endl;
}
void fun1(void)
{
std::cout << "in fun1(void)\n";
std::cout << "Use my value = " << usemyvalue<< std::endl;
if (usemyvalue==1)
{
std::cout << "Using fun1(int) with a value!\n";
fun1((int)myvalue); // remember to cast as an int here
}
else
{
//normal fun1()code here
std::cout << "No var passed!\n";
std::cout << "Running standard non parametrised code!\n";
}
}
#pragma startup fun1
int main()
{
std::cout << "now running main function.\n";
std::cout << "Hello World\n";
return 0;
}
I suspect that the second method would also work with Borlands compiler but without access to it I cannot swear to that.
Hope this helps!
I can neither find any documentation on your compiler, nor use the compiler itself to check my guess. But from what I remember, #pragma startup takes function without arguments and returning void.
I would further guess that your code is not going to work if you leave only function taking int argument.
Disregarding that, I think it's not possible to pass an argument to function called in such a way.
As a solution I would propose you creating wrapper function, calling whatever function you would like with necessary arguments, like:
void start()
{
#pragma startup start
fun1( global_var_name );
}
I'm not exactly sure I understand the restrictions, but how about simply defining another function with a different name to forward to the function you want?
void fun2() { fun1(42); }
#pragma startup fun2 100
I am trying to benchmark many (about 25) variations of an algorithm written in C++.
I implemented these variations using a combination of three methods:
copying code and making minor changes to the copied version
subclassing the base algorithm class
using #ifdefs to switch between snippets of code
The variations that arise from options 1 and 2 are okay because I can select which variation of the algorithm to run in a configuration file. I can then iterate through different configuration files and keep a record of "configuration:results" pairs - keeping these records is very important to my work.
I am currently having a problem with the #ifdefs because I have to compile multiple versions of the code to access these variations, making it much harder to run automated experiment scripts and to keep accurate records of results. The #ifdefs, however, are very useful because if I find a mistake in one copy of the code, then I do not have to remember to correct this mistake in multiple copies.
The #ifdefs expand six variations that I created by both copying code and subclassing into 24 total variations (4 variations for each basic variation).
Here is an example - mostly the I am using the #ifdefs to avoid replicating too much code:
....
double lasso_gam=*gamma;
*lasso_idx=-1;
for(int aj=0;aj<(int)a_idx.size();aj++){
int j=a_idx[aj];
assert(j<=C*L);
double inc=wa[aj]*(*gamma)*signs[aj];
if( (beta_sp(j)>0 && beta_sp(j)+inc<0)
#ifdef ALLOW_NEG_LARS
|| (beta_sp(j)<0 && beta_sp(j)+inc>0)
#else
|| (beta_sp(j)==0 && beta_sp(j)+inc<0)
#endif
){
double tmp_gam=-beta_sp(j)/wa[aj]*signs[aj];
if(tmp_gam>=0 && tmp_gam<lasso_gam) {
*lasso_idx=aj;
*next_active=j;
lasso_gam=tmp_gam;
}
}
}
if(lasso_idx>=0){
*gamma=lasso_gam;
}
....
Question: What is the best way to allow the multiple variations of the algorithm, which are currently specified by #ifdefs, to be run given a configuration file that specifies which variation of the algorithm to run.
Ideally I would like to compile the code only once and select an algorithm variation at runtime using the config file.
You can augment your algorithm with a (possibly additional) template argument like this:
enum class algorithm_type
{
type_a,
type_b,
type_c
};
template <algorithm_type AlgorithmType>
void foo(int usual, double args)
{
std::cout << "common code" << std::endl;
if (AlgorithmType == algorithm_type::type_a)
{
std::cout << "doing type a..." << usual << ", " << args << std::endl;
}
else if (AlgorithmType == algorithm_type::type_b)
{
std::cout << "doing type b..." << usual << ", " << args << std::endl;
}
else if (AlgorithmType == algorithm_type::type_c)
{
std::cout << "doing type c..." << usual << ", " << args << std::endl;
}
std::cout << "more common code" << std::endl;
}
Now you can select your behavior via this template argument:
foo<algorithm_type::type_a>(11, 0.1605);
foo<algorithm_type::type_b>(11, 0.1605);
foo<algorithm_type::type_c>(11, 0.1605);
The type, being a constant expression, yields a compile-time decided branch (that is, the others are known to be dead code and removed). In fact, your compiler should warn you about this (how you deal with that is up to you).
But you can still dispatch off a runtime value just fine:
#include <stdexcept>
void foo_with_runtime_switch(algorithm_type algorithmType,
int usual, double args)
{
switch (algorithmType)
{
case algorithm_type::type_a:
return foo<algorithm_type::type_a>(usual, args);
case algorithm_type::type_b:
return foo<algorithm_type::type_b>(usual, args);
case algorithm_type::type_c:
return foo<algorithm_type::type_c>(usual, args);
default:
throw std::runtime_error("wat");
}
}
foo_with_runtime_switch(algorithm_type::type_a, 11, 0.1605);
foo_with_runtime_switch(algorithm_type::type_b, 11, 0.1605);
foo_with_runtime_switch(algorithm_type::type_c, 11, 0.1605);
The internals of the algorithm remain the same (dead branches eliminated, same optimizations), just how you get there has changed. (Note that it's possible to generalize the enum idea so that this switch is generated automatically; if you find yourself with handfuls of variations, this might be good to learn.)
And of course you still can #define a specific algorithm as a default:
#define FOO_ALGORITHM algorithm_type::type_a
void foo_with_define(int usual, double args)
{
return foo<FOO_ALGORITHM>(usual, args);
}
foo_with_define(11, 0.1605);
All these together give you the advantages of all three, with no repetition.
In practice, you can have all three as overloads: one for users who know which algorithm to use at compile-time, those who need to select it at runtime, and those who just want a default (which you can override via a project-wide #define):
// foo.hpp
enum class algorithm_type
{
type_a,
type_b,
type_c
};
// for those who know which algorithm to use
template <algorithm_type AlgorithmType>
void foo(int usual, double args)
{
std::cout << "common code" << std::endl;
if (AlgorithmType == algorithm_type::type_a)
{
std::cout << "doing type a..." << usual << ", " << args << std::endl;
}
else if (AlgorithmType == algorithm_type::type_b)
{
std::cout << "doing type b..." << usual << ", " << args << std::endl;
}
else if (AlgorithmType == algorithm_type::type_c)
{
std::cout << "doing type c..." << usual << ", " << args << std::endl;
}
std::cout << "more common code" << std::endl;
}
// for those who will know at runtime
void foo(algorithm_type algorithmType, int usual, double args)
{
switch (algorithmType)
{
case algorithm_type::type_a:
return foo<algorithm_type::type_a>(usual, args);
case algorithm_type::type_b:
return foo<algorithm_type::type_b>(usual, args);
case algorithm_type::type_c:
return foo<algorithm_type::type_c>(usual, args);
default:
throw std::runtime_error("wat");
}
}
#ifndef FOO_ALGORITHM
// chosen to be the best default by profiling
#define FOO_ALGORITHM algorithm_type::type_b
#endif
// for those who just want a good default
void foo(int usual, double args)
{
return foo<FOO_ALGORITHM>(usual, args);
}
Of course, if some implementation types are always worse than some other, get rid of it. But if you find there are two useful implementations, there's no harm in keeping both around this way.
If you have multiple versions with #ifdefs, its usually best to build multiple executables and have your configuration script decide which executable(s) to run when benchmarking. You then have rules in your Makefile to build the various configurations:
%-FOO.o: %.cc
$(CXX) -c $(CFLAGS) -DFOO -o $# $<
%-BAR.o: %.cc
$(CXX) -c $(CFLAGS) -DBAR -o $# $<
test-FOO: $(SRCS:%.cc=%-FOO.o)
$(CXX) $(LDFLAGS) -DFOO -o $# $^ $(LDLIBS)
If your #ifs are scattered all around and change a line of code here or there then turn all your #ifs into ifs based on an enum passed into the function for which variation to run and hope the compiler does a great job at optimizing. Hopefully it will generate almost the same code as having defined the function multiple times except with a single run time condition to decide which to run. No promises.
If you are #ifing a block of code in the algorithm split the algorithm up into smaller functions that your different implementations of the whole algorithm can call. This is obviously impractical if your #ifs were so intrusive that you would wind up with 50 functions though.
You haven't mentioned what compiler you're using, but you can set #defines on the command line for any of them. In gcc, all you would need is to add -D MYTESTFOO to define MYTESTFOO. That would make #defines the way to go - no code changes to propagate, and sure, you'll have different compiled code for each test, but it should be easy to automate.
If you place the algorithms themselves inside classes with the same interface, you can pass them as template parameters to the place using the algorithm.
class foo {
public:
void do_something() {
std::cout << "foo!" << std::endl;
}
}
class bar {
public:
void do_something() {
std::cout << "bar!" << std::endl;
}
template <class meh>
void something() {
meh algorithm;
meh.do_something();
}
int main() {
std::vector<std::string> config_values = get_config_values_from_somewhere();
for (const austo& config : config_values) { // c++11 for short notation
switch (config) {
case "foo":
something<foo>();
break;
case "bar":
something<bar>();
break;
default:
std::cout << "undefined behaviour" << std::endl;
}
}
}
This way you can use the different behaviours at the same time and distinguish between them by their names. Also if you do not use one of them it will be removed by the optimizer at compile time (not in your problem though).
When reading the configuration file, you just need a factory (or similar) to create the correct instance of the object / function that should use the algorithm before using the algorithm.
Edit: added basic switch.
One way would NOT to include the preprocessor directives in the executable, and do it thusly:
#define METHOD METHOD1
int Method1() { return whatever(); };
#undef METHOD
#define METHOD METHOD2
int Method2() { return whatever(); };
#undef METHOD
Assuming whatever is reliant on METHOD then these would give different results.
EDIT: The code marked as "not working" was actually working. It was because of a syntax problems in my tests, not detected by the compiler. So the question is already solved, thank you.
C++ is not a language I use everyday, so it is possible that the solution is trivial.
About the context first. I use C++ to develop on a microcontroller (Arduino-based, AVR microcontroller), so I do not use the STL, printf-like functions, new/malloc should be avoided and C++ <string> too.
I have an object called Serial similar to the C++ cout iostream, to communicate with the microcontroller with a serial interface. I have overloaded the "<<" operator of the class from which Serial is an instance so I can do something like that:
Serial << "debug " << "value is " << 3 << endl;
// Whithout the << operator it would be:
Serial.print("debug ");
Serial.print("value is ");
Serial.println(3);
I would like to create a function (or a macro) that enables this kind of line only if debugging is enabled, and which automatically add the "debug" string and append the "endl" value at the end.
So something like that (warning, code does not work because "data" cannot expand as a whole C++ instruction):
#ifdef DEBUG
#define PRINT_DEBUG(data) do {Serial << "debug " << data << endl;} while(0)
#else
#define PRINT_DEBUG(data) do {} while(0)
#endif
// This code works
PRINT_DEBUG("hello world");
// This code does not work
int value1 = 3;
char * value2 = "this is a string";
PRINT_DEBUG("sensor1 value:" << value1 << " other sensor value " << value2);
This kind of function/macro would allow me to easily output strings on my serial interface with a specific "string protocol" without having to repeat the "debug" string at the start. It would also allow me to easily disable the print of debug message by not setting the DEBUG macro. I also have only one "#ifdef DEBUG" instead of several ones in my code.
I managed to do something like that with variadic arguments, but I hate this solution because it is dangerous to use (I do not want to specify the number of arguments), and I cannot mix different type of data:
void __rawSend(char * args, ...) {
Serial.print(args);
va_list paramList;
va_start (paramList, args);
while(true) {
char * next = va_arg(paramList, char*);
if (next == NULL) {
break;
}
Serial.print(" ");
Serial.print(next);
}
Serial.println();
va_end(paramList);
}
#ifdef DEBUG
#define printDebug(...) do {__rawSend(OUTPUT_DEBUG, __VA_ARGS__, NULL);} while(0)
#else
#define printDebug(...) do {} while(0)
#endif
int intValue = 1;
char * stringValue = "data";
// This works
printDebug("hello",stringValue);
// This does not works
printDebug("data is", intValue);
How can I do that? Is it possible with macros (while avoiding variadic arguments and mixing different kind of types)? Is there a better solution?
Sorry all, the code marked as "not working" does actually work. It was because of a syntax problems in my tests, not detected by the compiler.
Anyway, my solution can benefit other people working with Arduino, as I have seen solutions using printf or trying to recreate printf.
I used the "<<" operator coming from http://arduiniana.org/libraries/streaming/
I tend to avoid macros for this sort of things and use classes and static polymoprhism instead :
// Define different types providing a stream interface
struct DebugStream
{
template <typename T>
std::ostream & operator<< (const T & x) const {
return Serial << "debug " << x;
}
// This one is for stream manipulators
std::ostream & operator<< (std::ostream& (*x) (std::ostream&)) const {
return Serial << "debug " << x;
}
};
// This type also provides a stream-like interface but does nothing
struct NoStream
{
template <class T>
const NoStream & operator<< (const T & x) const {
return *this;
}
const NoStream & operator<< (std::ostream& (*x) (std::ostream&)) const {
return *this;
}
};
// Instanciate a debug object having one of the previously defined types
//
// Make sure to declare debug in a common .hxx file included everywhere else
// but to define it only once in a .cxx file.
#ifdef DEBUG
DebugStream debug;
#else
NoStream debug;
#endif
// Use it like you would use the Serial iostream
debug << "value is " << 3 << std::endl;
Since everything is inlined and exact types are known at compile-time, the compiler can optimize out all unnecessary operations on NoStream instances.
If I understand your problems correctly...
Looks to me like you need to overload operator<< for all types you're going to send to the debug interface.
The var args macro has to have a way to deduce the types of its arguments. The way you have it implemented it's expecting all C type strings. You'd be better off with printf or a library like fastformat.
If your operator<< is not returning a reference to the class that allows operator<< to be chained, you'll get errors like "I have the following error for the line "DEBUG("hello" << " " << "world");" : invalid operands of types 'const char [6]' and 'const char [2]' to binary 'operator<<' ". I do not believe DEBUG("hello" << " " << "world"); can be made to work. DEBUG( "hello", "world"); might work.
What (if any) are some potential problems with a C++ macro usage like this?
Would an inline function be a more appropriate solution?
#define EVENT_INFO(_format_, ...) CMyEvent::Generate(__FILE__, __LINE__, CMyEvent::EVT_HIGH, _format_, __VA_ARGS__)
void
CMyEvent::Generate(
const char* file, // filename
int line, // line number
CMyEvent::LEVEL level, // severity level
const char *format, // format of the msg / data
...) // variable arguments
{
// Get a message from the pool
CMyEvent* p_msg = GetMessageFromPool();
if(p_msg != NULL)
{
va_list arguments; // points to each unnamed argument
va_start(arguments, format);
// Fill the object with strings and data.
p_msg->Fill(file, line, level, 0, format, arguments);
va_end(arguments);
}
}
As you're using C++, you can avoid the pitfalls of using variable argument lists which are subject to many problems:
No check on quantity of arguments
No check on argument type
To make it more C++, do something like:
#define EVENT_INFO(args) EventLogStream (__FILE__, __LINE__, __PRETTY_FUNCTION__) << args
and invoke it like (warning: all code here is pseudocode and may be syntactically incorrect, but you should get the basic idea):
EVENT_INFO ("The answer to " << the_question << " is " << answer); // usually 42
The EventLogStream is similar to the cout object and like cout, you can provide class specific output:
class Vector3D
{
EventLogStream &operator << (EventLogStream &out) { out << "{" << x << ", " << y << ", " << z << "}"; }
}
If you could rewrite your messaging to use operator<<(), perhaps using std::ostreams with a custom stream buffer, you wouldn't need variable arguments or the ugly (IMHO) macro, and it would look a lot more like C++ than C.
variadic macro is great for use on logging. much better than using iostreams. inline function won't work unless you are willing to pass __FILE__, __LINE__ manually.
You can enclose format with parentheses for safety (not necessary IMHO)