Link to home
Start Free TrialLog in
Avatar of sneeuw
sneeuwFlag for Belgium

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
Avatar of MT_MU
MT_MU

Maybe...

#if LogSwitch
#define LogMsg(x) AddToLogFile(x)
#else
#define LogMsg(x)
#endif
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.
Avatar of sneeuw

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 !
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.
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.
Avatar of sneeuw

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 ?
Avatar of sneeuw

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 ??
In main.h...


include the line if you want to log

#define LOGGING

don't include anything if you don't want logging.

Avatar of sneeuw

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).
Avatar of sneeuw

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.  




Okay - so I almost got it...

#ifdef LOGGING
#define Log(kind, Mesg) AddToLog(kind, Mesg)
#else
#define Log(king, Mesg)
#endif




Avatar of sneeuw

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") ;
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.




Avatar of sneeuw

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'      
Avatar of sneeuw

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.
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.
Avatar of sneeuw

ASKER

Adjusted points from 100 to 150
Avatar of sneeuw

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
ASKER CERTIFIED SOLUTION
Avatar of MT_MU
MT_MU

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of sneeuw

ASKER

Thanks for your time and effort