about marco in VC6

L

liwei

how can i let the follow marco works in VC6.0
#define TRACE_BEGIN(function) #ifdef DEBUG \

printf("----------------Enterinto%s-----------------\n",function);\
time_t beginTime,endTime;\
time(&beginTime); \
#endif
 
A

Alf P. Steinbach

* liwei:
how can i let the follow marco works in VC6.0
#define TRACE_BEGIN(function) #ifdef DEBUG \

printf("----------------Enterinto%s-----------------\n",function);\
time_t beginTime,endTime;\
time(&beginTime); \
#endif

First off, #define does not define things with preprocessor directive like
#ifdef in them. There's only one round of preprocessing of the text.

Second, DEBUG isn't a standard symbol, but NDEBUG (with opposite meaning)
is; NDEBUG is defined by <cassert>.

So, something like

#include <cassert>

#ifndef NDEBUG
# undef DEBUG
# define DEBUG
#endif

in a common miscellany header file, and then (including that header)

#ifndef DEBUG
# define TRACE_BEGIN( function )
#else
# define TRACE_BEGIN( function ) \
# printf ... \
#endif

However, the above is a C-style of doing things, and it's not only awkward
but can interact destructively with the client code.

In C++ you'd define a Tracer class and create a trace object, letting the
constrcutor do the TRACE_BEGIN things, and the destructor the TRACE_END
things. You might still use a macro to compile-time conditionally create a
Trace object or not. But again, that would be C-style; in C++ it would be
more natural to do the equivalent of

#ifdef DEBUG
# typedef Tracer int
#else
# typedef Tracer TracerImpl
#endif

To avoid all that preprocessing stuff everywhere you could use it once to
define a bool isDebugBuild constant, but explaining how to use that would go
beyond what's natural to discuss here.
 
R

red floyd

Alf said:
#ifdef DEBUG
# typedef Tracer int
#else
# typedef Tracer TracerImpl
#endif

Because TracerImpl might (and probably does) have params to its
constructor, how about:

// PSEUDOCODE
template <bool b> class TracerImpl;
template<>
class TracerImpl<true> {
TracerImpl(sometype arg, etc...) // pseudocode
{
// do entry trace
}
~TracerImpl()
{
// do exit trace;
}
};
template<>
class TracerImpl<false> {
TracerImpl(sometype arg, etc...) { } // pseudocode
~TracerImpl() { }

};
#ifdef DEBUG
typedef TracerImpl<true> Tracer;
#else
typedef TracerImpl<false> Tracer;
#endif
 
M

msalters

red floyd schreef:
Because TracerImpl might (and probably does) have params to its
constructor, how about:

// PSEUDOCODE
template <bool b> class TracerImpl;
template<>
class TracerImpl<true> {
TracerImpl(sometype arg, etc...) // pseudocode
{
// do entry trace
}

That runs into the forwarding problem. However, if you replace
int by (void), it should work in all cases. The reason is that
(void)(arg1,arg2) is a cast expression, and , the comma operator.

HTH,
Michiel Salters
 
R

red floyd

msalters said:
red floyd schreef:



That runs into the forwarding problem. However, if you replace
int by (void), it should work in all cases. The reason is that
(void)(arg1,arg2) is a cast expression, and , the comma operator.

HTH,
Michiel Salters

What forwarding problem is that? Both template specializations are
fully defined, and we simply use the #ifdef/typedef combo to select
between them.

If you want to avoid templates:

class TracerImpl {
public:
TracerImpl(args) // PSEUDOCODE
{
#ifdef DEBUG
// tracing stuff here
#endif
}
~TracerImpl()
{
#ifdef DEBUG
// tracing stuff here
#endif
}
};
 
K

Kevin Handy

liwei said:
how can i let the follow marco works in VC6.0
#define TRACE_BEGIN(function) #ifdef DEBUG \

printf("----------------Enterinto%s-----------------\n",function);\
time_t beginTime,endTime;\
time(&beginTime); \
#endif

You can't use '#' expressions inside of a #define.
"It just doesn't work"(tm)

If you have a decent optimizer, you can use this version
and let the optimizer strip out the code when not needed.

#define TRACE_BEGIN(function) time_t beginTime,endTime;\
if (DEBUG) \
{printf("----------------Enterinto%s-----------------\n",function);\
time(&beginTime);}

It has the added benefit of checking your code for
syntax problems no matter how you compile it.

Or, you can swap the # directives around

#ifdef DEBUG
#define TRACE_BEGIN(function) \
printf("----------------Enterinto%s-----------------\n",function);\
time_t beginTime,endTime;\
time(&beginTime);
#else
#define TRACE_BEGIN(function)
#endif

If you are using am 'assert' package, you might want
to use NDEBUG instead of DEBUG, just to be consistant.

If you want to profile your code, doesn't VC have a code
profiling option? Most functions take so little time that
you will find that your profiling code is taking most of the
cpu-time, especially since printf is a slow bastard,
which skews your results. This is magnified if your
'TRACED' function calls other 'TRACED' functions.
You end up profiling your calls to printf, and optimizing
the wrong functions.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top