sneeuw
asked on
COmpiler switch conditional log function ??
Hi guys,
Using Borland cpp Builder 4.x
I want to do the following :
- Add debug logging features to my code which can be built via a compiler switch.
- For this I would like one or two dedicated functions. e.g.
Log.AddToLogFile(char *Message) ;
Questions :
- How do I best use the compiler switch ? Add in the main .h file ??
- I can of course place a switch before and after every time I call the function. e.g. :
#if LogSwitch
Log.AddToLogFile(char *Message) ;
#endif
But this would require me to add three lines per call.
I can also add the swithc in the function itself :
e.g. :
void AddToLogFile (char * Message)
{
#if LogSwitch
LogToFile (file,Message) ;
#endif
}
But won't this slow down code that is built without the switch ?? Each time calling this function ??
The idea is to have one or more functions that do the logging but which can be switched off easily without any performance penalty when switched off ??
Thanks
Using Borland cpp Builder 4.x
I want to do the following :
- Add debug logging features to my code which can be built via a compiler switch.
- For this I would like one or two dedicated functions. e.g.
Log.AddToLogFile(char *Message) ;
Questions :
- How do I best use the compiler switch ? Add in the main .h file ??
- I can of course place a switch before and after every time I call the function. e.g. :
#if LogSwitch
Log.AddToLogFile(char *Message) ;
#endif
But this would require me to add three lines per call.
I can also add the swithc in the function itself :
e.g. :
void AddToLogFile (char * Message)
{
#if LogSwitch
LogToFile (file,Message) ;
#endif
}
But won't this slow down code that is built without the switch ?? Each time calling this function ??
The idea is to have one or more functions that do the logging but which can be switched off easily without any performance penalty when switched off ??
Thanks
You can have code someting like:
#ifdef LOG_SWITCH
#define LogMsg(x) AddtoLogFile(x)
#else
#define LogMsg(x)
#endif
In your make file you can pass: -DLOG_SWITCH to the C compiler when you want the log messages and -ULOG_SWITCH when it is not required
(probaly on the release version of your software).
This will not slow down your execution time because it is expanded during
compilation time and LogMsg(x) will be expanded to nothing during
compilation when LOG_SWITCH is not defined.
#ifdef LOG_SWITCH
#define LogMsg(x) AddtoLogFile(x)
#else
#define LogMsg(x)
#endif
In your make file you can pass: -DLOG_SWITCH to the C compiler when you want the log messages and -ULOG_SWITCH when it is not required
(probaly on the release version of your software).
This will not slow down your execution time because it is expanded during
compilation time and LogMsg(x) will be expanded to nothing during
compilation when LOG_SWITCH is not defined.
ASKER
So when LOG_SWITCH is true LogMsg(x) will not exist anymore ???
I'm not really familiar with this kind of constructions so I'm trying to understand !
I'm not really familiar with this kind of constructions so I'm trying to understand !
Actually when LOG_SWITCH is defined using the compiler flag -DLOG_SWITCH,
LogMsg(x) will be expanded to AddtoLogFile(x) and when
it is undefined ie. using -ULOG_SWITCH, LogMsg(x) will be expanded to
nothing.
LogMsg(x) will be expanded to AddtoLogFile(x) and when
it is undefined ie. using -ULOG_SWITCH, LogMsg(x) will be expanded to
nothing.
also, a good compiler should know how to remove calls to fuctions which become empty after preproccessing.
If you make the funtion AddLogToFile to static, most of the compilers
removes the code. I have seen the new VC 6.0 compiler
give a warning after removing such code.
Also if you decalare the function AddLogToFile() itself undef #ifdef
LOG_SWITCH, then we are sure that no code is generated.
removes the code. I have seen the new VC 6.0 compiler
give a warning after removing such code.
Also if you decalare the function AddLogToFile() itself undef #ifdef
LOG_SWITCH, then we are sure that no code is generated.
ASKER
> also, a good compiler should know how to remove calls to fuctions which become empty after preproccessing
Does Borland cpp Builder 4 qualify as a good compiler ?
Does Borland cpp Builder 4 qualify as a good compiler ?
ASKER
Please tell me ...
Will the following work :
in the main.h :
----------------
#define LOGGING 0x01
In the logging class :
Logging.h :
-----------
#ifdef LOGGING
#define Log(char *kind, char *Mesg) AddToLog(char *kind, char *Mesg)
#else
#define Log(char *kind, char *Mesg)
#endif
Where : AddToLog is a fully working function declared in logging.h and coded in logging.cpp.
And so, if in the main, the #define LOGGING is NOT done or set to 0x00, the function will not exist !????
Will this work or do I need to do this via the make file ??
Will the following work :
in the main.h :
----------------
#define LOGGING 0x01
In the logging class :
Logging.h :
-----------
#ifdef LOGGING
#define Log(char *kind, char *Mesg) AddToLog(char *kind, char *Mesg)
#else
#define Log(char *kind, char *Mesg)
#endif
Where : AddToLog is a fully working function declared in logging.h and coded in logging.cpp.
And so, if in the main, the #define LOGGING is NOT done or set to 0x00, the function will not exist !????
Will this work or do I need to do this via the make file ??
In main.h...
include the line if you want to log
#define LOGGING
don't include anything if you don't want logging.
include the line if you want to log
#define LOGGING
don't include anything if you don't want logging.
ASKER
Following seems to work :
in one module
#define LOGGING // Value doesn't matter
#ifdef LOGGING
#define Log AddToLog
#else
#define Log
#endif
But when I place this bit in another class, and use Instance.Log(...) I get error messages saying Log isn't a part of the class ? (not a member of the class).
in one module
#define LOGGING // Value doesn't matter
#ifdef LOGGING
#define Log AddToLog
#else
#define Log
#endif
But when I place this bit in another class, and use Instance.Log(...) I get error messages saying Log isn't a part of the class ? (not a member of the class).
ASKER
I get errors when I define the functions fully in the Macro but only the name seems to work.
Opps...
#ifdef LOGGING
#define Log(kind, Mesg) AddToLog(kind, Mesg)
#else
#define Log
#endif
#defines are simple text replacement.
#ifdef LOGGING
#define Log(kind, Mesg) AddToLog(kind, Mesg)
#else
#define Log
#endif
#defines are simple text replacement.
Okay - so I almost got it...
#ifdef LOGGING
#define Log(kind, Mesg) AddToLog(kind, Mesg)
#else
#define Log(king, Mesg)
#endif
#ifdef LOGGING
#define Log(kind, Mesg) AddToLog(kind, Mesg)
#else
#define Log(king, Mesg)
#endif
ASKER
Any idea what I have to do to get it to work in a seperate class.
e.g. in the main.h
#define LOGGING
In the Class :
#ifdef LOGGING
#define Log(kind, Mesg) AddToLog(kind, Mesg)
#else
#define Log(king, Mesg)
#endif
in the main again :
Instance.Log("text",text") ;
e.g. in the main.h
#define LOGGING
In the Class :
#ifdef LOGGING
#define Log(kind, Mesg) AddToLog(kind, Mesg)
#else
#define Log(king, Mesg)
#endif
in the main again :
Instance.Log("text",text")
That's a different case....
in a class definition use something like...
class MyClass : public
{
#ifdef LOGGING
void AddToLog(char *kind, char *Mesg);
#else
void AddToLog(char *kind, char *Mesg) {};
};
This should attempt to "inline" the AddToLog when Logging is undefined. The compiler should optimize it out.
in a class definition use something like...
class MyClass : public
{
#ifdef LOGGING
void AddToLog(char *kind, char *Mesg);
#else
void AddToLog(char *kind, char *Mesg) {};
};
This should attempt to "inline" the AddToLog when Logging is undefined. The compiler should optimize it out.
ASKER
Hi,
I don't get that to work (Compiler error when I define LOGGING or not):
E2171 Body has already been defined for function 'function'
I don't get that to work (Compiler error when I define LOGGING or not):
E2171 Body has already been defined for function 'function'
ASKER
OK,
I placed
#ifdef LOGGING
#endif
around the routine in the cpp file as well.
So if defined, the routin in the cpp is used, if NOT defined, the empty routine in the h file is used.
Bad news is that this function still exists after compiling and during run time, you can see that the empty routine is called each time !!
Also,
When I #define LOGGING in the main.h file, it doesn't seem to work. I have to define in the class header file itself, but that's not a problem.
I placed
#ifdef LOGGING
#endif
around the routine in the cpp file as well.
So if defined, the routin in the cpp is used, if NOT defined, the empty routine in the h file is used.
Bad news is that this function still exists after compiling and during run time, you can see that the empty routine is called each time !!
Also,
When I #define LOGGING in the main.h file, it doesn't seem to work. I have to define in the class header file itself, but that's not a problem.
Sorry forgot to mention that the #ifdef needed to be around the routine in the cpp as well.
The #define LOGGING has to be included in a header that will be included in both your main routine and the class header/cpp file.
For you to see the function being called means that you are running the program in a "debug" built w/o optimizations. When you build a release version the compiler should optimize out the empty call.
The #define LOGGING has to be included in a header that will be included in both your main routine and the class header/cpp file.
For you to see the function being called means that you are running the program in a "debug" built w/o optimizations. When you build a release version the compiler should optimize out the empty call.
ASKER
Adjusted points from 100 to 150
ASKER
Hi,
Sorry to nag but any idea how I can check whether my compiler really leaves it out ???
Borland might do it differently from Microsoft ??
I increased the points as appreciation for your time and effort
Sorry to nag but any idea how I can check whether my compiler really leaves it out ???
Borland might do it differently from Microsoft ??
I increased the points as appreciation for your time and effort
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks for your time and effort
#if LogSwitch
#define LogMsg(x) AddToLogFile(x)
#else
#define LogMsg(x)
#endif