Detect function call in printf()'s arguments - c++

For a long time now, we've had a logging system that worked much like this:
#define LOG( LEVEL, FORMAT, ... ) my_log_function( LEVEL, __FUNCTION__, \
__LINE__, FORMAT, __VA_ARGS__ )
my_log_function will check the level of logging currently in place, and if acceptable, will do some pretty printing (file/line where it was logged, time etc..) of the informations passed.
Now, problem is, this macro definition has two massive drawback:
1/ When used, the arguments passed in that macro are evaluated, which means lots of performance hits when your code is crowded by LOG() calls.
See example here:
LOG( INFO, "The parameters: %s %d %d\n", heavyMethod().name(),
heavyMethod2().id(), work_done_in_this_function());
Even if the "INFO" logging level is deactivated, all the parameters will be evaluated before entering the function.
If you log the function calls, you'll see this happening:
call to heavyMethod()
call to name()
call to heavyMethod2()
call to id()
call to work_done_in_this_function()
(at last) call to my_log_function()
That's pretty bad when you have 1000's of LOG() calls.
Solution is simple: take out of my_log_function the code that checks the level and modify the LOG() definition like this:
#define LOG( LVL, FMT, ... ) do{ if( level_enabled(LVL) ) \
{ \
my_log_function( LVL, ...); \
} \
}while(0)
This makes sure that when the log level is not sufficient, the parameters are not evaluated (since they are in a bracket block).
2/ As you've seen in my example, the last function that is called is doing some sort of work that wouldn't be done if the LOG() function wasn't called.
This happens quite a lot in our code (and I know, this SUCKS HARD, people have lost fingers to this already).
With the enhancement I made in point 1/, we now have to check every LOG() call to see if some work was done in there that isn't done anymore, now that we neutralized the calls.
This is where you guys enter: do you know a simple method that would check if an argument to a function is actually modifying something?
The project is in C++, and most functions that "don't modify anything" are marked as const.
Note that this includes some tricky things like: LOG( INFO, "Number of items: %d\n", _item_number++);, where _item_number is an object's class member (thus doesn't get incremented if INFO level is not activated :-( ).
TL;DR: NEVER, NEVER do work in printf(). ALWAYS do it beforehand:
// BAD
printf("Number: %d\n",++i);
// GOOD
i++;
printf("Number: %d\n", i);

Basically, you're trying to check for pure functions (i.e. ones which have no side effects). An easy way to check this is to check that it does not make any writes to global memory.
GCC supports a couple of ways of enforcing this. First, there is the const attribute, which when applied to a function, causes it not to be able to read or write from global memory (only its own stack). The issue is, this may be a little restrictive for what you want.
There's also the pure attribute, which is basically the same, but allows for access from global memory, but not to it, which should also enforce what you want.
Each of these are applied by putting __attribute__(pure) (or __attribute__(const)) by the method declaration. Sadly, I don't think there's a way of enforcing this per call, although there may be a way using function pointers. I'll update if I find one.
Ref: http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
EDIT: As listed here, it may be possible to apply this to a function pointer although I don't think there's a way to do it without embedding a function pointer into each method call in your macro (which needs to know the argument layout of each function, anyway) or declaring all your functions as pure.
EDIT2: Yeah, this also won't catch things like i++ in your parameter lists. Those will have to be done using some regex magic I think.

Related

Is using cpp macros as scripting language a bad thing?

)
well this is my situationI'm working on Cpp/Qt project where we have some predefined routines to allocate array memory
ex:
alloc2(n1, n2, s) return a pointer to a 2d (n1*n2) array of elements of size "s"
if allocation fails it will return a NULL
I wrote some macros to make an easy call to those routines and in case memory allocation fails it will write an error message and exit the current block of code.
#define ALLOC2(p, n1, n2, size) if(NULL == (p=alloc2((n1), (n2), (size)))){ \
TheConsole->Message(QString("ERROR MSG")); \
return false; \
}
of course, the macros have to be called properly, and n1, n2 have to be only of int type
but one of the advantages here is that I don't have to pass a the pointer of "TheConsole" as macros may work as "scripting" language; it will replace blindly "ALLOC2(p, n1, n2, size)" by its definition.
My question is:
I have 144 macro like this different types and dimensions and each is called in the code handers of times, is this way of using macros will cause some "Code bloat" or slow in some way my program??
we have some predefined routines
You use functions to encapsulate those.
in case memory allocation fails it will write an error message and exit the current block of code.
You throw an exception for that. Also, you shouldn't allocate memory manually most of the time.
of course, the macros have to be called properly
Which makes them unsafe.
but one of the advantages here is that I don't have to pass a the pointer of "TheConsole"
Which is hardly an advantage, considering C++'s primitives for sharing state.
Other than making debugging difficult and coding confusing, I cannot understand a sane reason for using macros for such tasks, especially if there are 144 like these.
EDIT: After reading the OP's comments I believe that he has some misconception of macros.
Macros are nothing but abbreviation of code. For example WYSIWYG is an abbreviation of What You See Is What You Get. Now when you define this as a macro, you just have to type WYSIWYG instead of What You See Is What You Get. This saves a lot of typing, yes, but using functions is a much better alternative.
When a compiler sees a macro, it simply replaces your abbreviation with the full form; similar to Find and Replace. Obviously there is no effect on the performance of your software, but rather your compile time is increased.

Disable function call from code base

Based on a poorly stated and recently deleted SO question ("Is it possible to call a function without calling it?") I have a similar question, hopefully put in a more logical perspective.
Is it possible / what are the best practices, to disable a function call from a codebase ? By disabling I don't mean greping through the whole code to manually comment out the function (which is a valid but somewhat tedious task). The only ways I can think of are
Returning as soon as entering function
ret_type foo()
{
return ret_type();
// actual implementation is not allowed to run
}
which would be a bit dangerous when the return code is used by caller functions.
Replace the declaration with an idle macro
ret_type foo();
#define foo() do { void; } while (0);
Is there a standard way, maybe a compiler hook, a pragma directive to do this and if not what are some other ways?
Is there a standard way, maybe a compiler hook, a pragma directive to do this and if not what are some other ways?
Let's just think for a minute, together. Let's consider two main cases:
the function returns void
the function returns something
In the first case you can simply take the body of the function and comment it out. BOOM: disabled.
In the second case you have a return value. Let's consider other two cases:
the returned value is used
the returned value is not used
In the first case you should ask yourself: can I return a dummy value and get away with it? If the answer is yes, then do so. If not, then you can't do anything about it except refactor your entire code.
In the second case you can comment it out, but why you are returning a value in the first place.

c++ va_arg typecast issue

All,
I am writing a small c++ app and have been stumped by this issue. Is there a way to create (and later catch ) the error while accessing element from va_list macro using va_arg if element type is not expected. Eg:-
count=va_arg(argp,int);
if (count <= 0 || count > 30)
{
reportParamError(); return;
}
Now, if I am passing a typedef instead of int, I get garbage value on MS compiler but 95% of time count gets value 0 on gcc (on 64 bit sles10 sys). Is there a way I can enforce some typechecking, so that I get an error that can be caught in a catch block?
Any ideas on this would be very helpful to me. Or is there a better way to do this. The function prototype is:-
void process(App_Context * pActx, ...)
The function is called as
process(pAtctx,3,type1,type2,type3);
It is essential for pActx to be passed as 1st parameter and hence cannot pass count as 1st parameter.
Update-1
Ok, this sounds strange but nargs does not seem to part of va_list on sles10 gcc. I had to put in
#ifdef _WIN32
tempCount=va_arg(argp,int)
#endif
After using this, parameters following nargs do not get garbage values. However, this introduces compiler/platform based #ifdefs....Thanks Chris and Kristopher
If you know a count will always be passed as the second argument, then you could always change the signature to this:
void process(App_Context * pActx, int count, ...)
If that's not an option, then there is really no way to catch it. That's just how the variable-argument-list stuff works: there is no way for the callee to know what arguments are being passed, other than whatever information the caller passes.
If you look into how the va_arg macro and related macros are implemented, you may be able to figure out how to inspect all the stuff on the stack. However, this would not be portable, and it is not recommended except as a debugging aid.
You also might want to look into alternatives to variable-arguments, like function overloading, templates, or passing a vector or list of arguments.
No, there is no way. varargs doesn't provide any way to check the types of parameters passed in. You must only read them with the correct type which means that you need another way of communicating type information.
You are likely to be better off avoiding varargs functionality unless you really need it. It's only really a C++ feature for the sake of legacy functions such as printf and friends.

How to separate logging logic from business logic in a C program? And in a C++ one?

I am currently coding in C and I have lots of printfs so that I can track, at some times, the flow of my application. The problem is that some times I want more detail than others, so I usually spend my time commenting/uncommenting my C code, so I can get the appropriate output.
When using Java or C#, I can generally separate both my implementation code from the logging logic by using Aspects.
Is there any similar technique you use in C to get around this problem?
I know I could put a flag called DEBUG that could be either on or off, so I wouldn't have to go all around and comment/uncomment my whole code every time I want to either show or hide the printfs. The question is I'd like to also get rid of the logging logic in my code.
If instead of C I was coding in C++, would it be any better?
Edit
It seems there is an AspectC++, so for C++ there seems to be a solution. What about C?
Thanks
IME you cannot really separate logging from the algorithms that you want to log about. Placing logging statements strategically takes time and experience. Usually, the code keeps assembling logging statements over its entire lifetime (though it's asymptotic). Usually, the logging evolves with the code. If the algorithm changes often, so will usually the logging code.
What you can do is make logging as unobtrusive as possible. That is, make sure logging statements always are one-liners that do not disrupt reading the algorithm, make it so others can insert additional logging statements into an existing algorithm without having to fully understand your logging lib, etc.
In short, treat logging like you treat string handling: Wrap it in a nice little lib that will be included and used just about everywhere, make that lib fast, and make it easy to use.
Not really.
If you have variadic macros available, you can easily play games like this:
#ifdef NDEBUG
#define log(...) (void)0
#else
#define log(...) do {printf("%s:%d: ", __FILE__, __LINE__); printf(__VA_ARGS__);} while(0)
#endif
You can also have logging that's turn-off-and-onable at a finer granularity:
#define LOG_FLAGS <something>;
#define maybe_log(FLAG, ...) do { if (FLAG&LOG_FLAGS) printf(__VA_ARGS__);} while(0)
int some_function(int x, int y) {
maybe_log(FUNCTION_ENTRY, "x=%d;y=%d\n", x, y);
... do something ...
maybe_log(FUNCTION_EXIT, "result=%d\n", result);
return result;
}
Obviously this can be a bit tedious with only allowing a single return from each function, since you can't directly get at the function return.
Any of those macros and calls to printf could be replaced with something (other macros, or variadic function calls) that allows the actual logging format and target to be separated from the business logic, but the fact of some kind of logging being done can't be, really.
aspectc.org does claim to offer a C and C++ compiler with language extensions supporting AOP. I have no idea what state it's in, and if you use it then of course you're not really writing C (or C++) any more.
Remember that C++ has multiple inheritance, which is sometimes helpful with cross-cutting concerns. With enough templates you can do remarkable things, perhaps even implementing your own method dispatch system that allows some sort of join points, but it's a big thing to take on.
On GCC you could use variadic macros: http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html . It makes possible to define dprintf() with any number of parameters.
Using additional hidden verbose_level parameter you can filter the messages.
In this case the logging loggic will only contain
dprintf_cond(flags_or_verbose_level, msg, param1, param2);
and there will be no need in separating it from the rest of code.
A flag and proper logic is probably the safer way to do it, but you could do the same at compile type. Ie. Use #define and #ifdef to include/exclude the printfs.
Hmm, this sounds similar to a problem I encountered when working on a C++ project last summer. It was a distributed app which had to be absolutely bulletproof and this resulted in a load of annoying exception handling bloat. A 10 line function would double in size by the time you added an exception or two, because each one involved building a stringstream from a looong exception string plus any relevant parameters, and then actually throwing the exception maybe five lines later.
So I ended up building a mini exception handling framework which meant I could centralise all my exception messages inside one class. I would initialise that class with my (possibly parameterised) messages on startup, and this allowed me to write things like throw CommunicationException(28, param1, param2) (variadic arguments). I think I'll catch a bit of flak for that, but it made the code infinitely more readable. The only danger, for example, was that you could inadvertently throw that exception with message #27 rather than #28.
#ifndef DEBUG_OUT
# define DBG_MGS(level, format, ...)
# define DBG_SET_LEVEL(x) do{}while(0)
#else
extern int dbg_level;
# define DBG_MSG(level, format, ...) \
do { \
if ((level) >= dbg_level) { \
fprintf(stderr, (format), ## __VA_ARGS__); \
} \
} while (0)
# define DBG_SET_LEVEL(X) do { dbg_level = (X); } while (0)
#endif
The ## before __VA_ARGS__ is a GCC specific thing that makes , __VA_ARGS__ actually turn into the right code when there are no actual extra arguments.
The do { ... } while (0) stuff is just to make you put ; after the statements when you use them, like you do when you call regular functions.
If you don't want to get as fancy you can do away with the debug level part. That just makes it so that if you want you can alter the level of debugging/tracing date you want.
You could turn the entire print statement into a separate function (either inline or a regular one) that would be called regardless of the debug level, and would make the decision as to printing or not internally.
#include <stdarg.h>
#include <stdio.h>
int dbg_level = 0;
void DBG_MGS(int level, const char *format, ...) {
va_list ap;
va_start(ap, format);
if (level >= dbg_level) {
vfprintf(stderr, format, ap);
}
va_end(ap);
}
If you are using a *nix system then you should have a look at syslog.
You might also want to search for some tracing libraries. There are a few that do similar things to what I have outlined.

Using C++ Macros To Check For Variable Existence

I am creating a logging facility for my library, and have made some nice macros such as:
#define DEBUG myDebuggingClass(__FILE__, __FUNCTION__, __LINE__)
#define WARING myWarningClass(__FILE__, __FUNCTION__, __LINE__)
where myDebuggingClass and myWarningClass both have an overloaded << operator, and do some helpful things with log messages.
Now, I have some base class that users will be overloading called "Widget", and I would like to change these definitions to something more like:
#define DEBUG myDebuggingClass(__FILE__, __FUNCTION__, __LINE__, this)
#define WARNING myWarningClass(__FILE__, __FUNCTION__, __LINE__, this)
so that when users call 'DEBUG << "Some Message"; ' I can check to see if the "this" argument dynamic_casts to a Widget, and if so I can do some useful things with that information, and if not then I can just ignore it. The only problem is that I would like users to be able to also issue DEBUG and WARNING messages from non-member functions, such as main(). However, given this simple macro, users will just get a compilation error because "this" will not be defined outside of class member functions.
The easiest solution is to just define separate WIDGET_DEBUG, WIDGET_WARNING, PLAIN_DEBUG, and PLAIN_WARNING macros and to document the differences to the users, but it would be really cool if there were a way to get around this. Has anyone seen any tricks for doing this sort of thing?
Declare a global Widget* const widget_this = NULL; and a protected member variable widget_this in the Widget class, initialized to this, and do
#define DEBUG myDebuggingClass(__FILE__, __FUNCTION__, __LINE__, widget_this)
Macros are basically a straight text substitution done by the preprocessor. There's no way for a macro to know the context from which it's being called to do the sort of detection you're interested in.
The best solution is probably separate macros as you suspect.
I don't think you can do this with a macro. You can probably manage to do it with SFINAE, but code that uses SFINAE (at least directly) is1 hard to write, harder to debug, and virtually impossible for anybody but an expert to read or understand. If you really want to do this, I'd try to see if you can get Boost enable_if (or a relative thereof) to handle at least part of the dirty work.
1 ...at least in every case I've ever seen, and I have a hard time imagining it being otherwise either.
Inspired by solipist, but slightly simpler in the implementation:
class Widget {
protected:
::myDebuggingClass myDebuggingClass(char const* file, char const* function, int line) {
return ::myDebuggingClass(file, function, line, this);
}
// ...
This eliminates the need for a shadowed variable; it relies on simple class name lookup rules.
The only way I can think of to possibly get this to work is to define a global variable:
Widget * this = NULL;
If that even compiles (I have my doubts, but don't have a compiler to test it), member functions will use the nearest scoped variable (the real his pointer), and everything else will get a null. Everyone's happy (so to speak...)
you could use weak reference to detect variable or function whether exist.
eg:
detect int a exist:
int a attribute((weak));
if (a)
exist
else
not exist