Solved

COmpiler switch conditional log function ??

Posted on 2000-04-18
22
209 Views
Last Modified: 2010-04-02
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
0
Comment
Question by:sneeuw
  • 11
  • 7
  • 3
  • +1
22 Comments
 
LVL 1

Expert Comment

by:MT_MU
ID: 2727352
Maybe...

#if LogSwitch
#define LogMsg(x) AddToLogFile(x)
#else
#define LogMsg(x)
#endif
0
 
LVL 1

Expert Comment

by:meerak
ID: 2727800
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.
0
 

Author Comment

by:sneeuw
ID: 2727994
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 !
0
 
LVL 1

Expert Comment

by:meerak
ID: 2728425
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.
0
 
LVL 1

Expert Comment

by:darkskyz
ID: 2728608
also, a good compiler should know how to remove calls to fuctions which become empty after preproccessing.
0
 
LVL 1

Expert Comment

by:meerak
ID: 2728630
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.
0
 

Author Comment

by:sneeuw
ID: 2729701
> 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 ?
0
 

Author Comment

by:sneeuw
ID: 2731003
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 ??
0
 
LVL 1

Expert Comment

by:MT_MU
ID: 2731047
In main.h...


include the line if you want to log

#define LOGGING

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

0
 

Author Comment

by:sneeuw
ID: 2731200
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).
0
 

Author Comment

by:sneeuw
ID: 2731210
I get errors when I define the functions fully in the Macro but only the name seems to work.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 1

Expert Comment

by:MT_MU
ID: 2731261
Opps...

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


#defines are simple text replacement.  




0
 
LVL 1

Expert Comment

by:MT_MU
ID: 2731270
Okay - so I almost got it...

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




0
 

Author Comment

by:sneeuw
ID: 2731575
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") ;
0
 
LVL 1

Expert Comment

by:MT_MU
ID: 2731724
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.




0
 

Author Comment

by:sneeuw
ID: 2734679
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'      
0
 

Author Comment

by:sneeuw
ID: 2734991
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.
0
 
LVL 1

Expert Comment

by:MT_MU
ID: 2735050
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.
0
 

Author Comment

by:sneeuw
ID: 2735875
Adjusted points from 100 to 150
0
 

Author Comment

by:sneeuw
ID: 2735876
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
0
 
LVL 1

Accepted Solution

by:
MT_MU earned 150 total points
ID: 2735913
Short of examining an assembly listing - there isn't anyway that I know of.

Obviously if you place anything in the function - it will not be optimized out.

Even should Borland leave it in - the affect on performance will be very very minimal.
0
 

Author Comment

by:sneeuw
ID: 2740040
Thanks for your time and effort
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

947 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now