Connecting Tech Pros Worldwide Forums | Help | Site Map

function trace

baibaichen
Guest
 
Posts: n/a
#1: Oct 16 '07
hi

our internal log apis support varargs, but do not support <<, it means
that we have to write funciton tracing like this:

printf("%s(%d,%f)", functionName,iCount,dTime);

this need us write format string mannualy each time.

I think the better style looks like:
#define BetterFunctionTrace ....


BetterFunctionTrace(functioName, iCount,dTime);

Is there any way to generate the format string in the compile time
accroding to parameter type and parameter number? i.e.

function1(int,char*,double) =%s(%d,%s,%f);
function2(int,char*,double,unsigned int) =%s(%d,%s,%f,%u);

any idea?

thanks


Justin Spahr-Summers
Guest
 
Posts: n/a
#2: Oct 16 '07

re: function trace


On Oct 16, 1:24 am, baibaichen <baibaic...@gmail.comwrote:
Quote:
Is there any way to generate the format string in the compile time
accroding to parameter type and parameter number? i.e.
>
function1(int,char*,double) =%s(%d,%s,%f);
function2(int,char*,double,unsigned int) =%s(%d,%s,%f,%u);
Part of the reason printf() and family use format strings is because
it's impossible to tell the number of arguments passed to a vararg
function, nor even the type of the next argument coming up. So
basically, you'd need to use a format string or some similar way of
passing information as a first parameter if your vararg list can
change a lot.

wijnand
Guest
 
Posts: n/a
#3: Oct 16 '07

re: function trace


Is this something you can use?

#include <iostream>
#include <string>


template <class T>
struct ToString;
// keep this empty to emit a compile time error
// when it doesn't have a associated string



// Define the format specifiers of the basic types
#define DEF0TYPE( type, str ) \
template < \
struct ToString< type \
{ static std::string value() { return str; } \
};

DEF0TYPE( int, "%d" )
DEF0TYPE( double, "%f" )
DEF0TYPE( char *, "%s" )
DEF0TYPE( const char *, "%s" )
DEF0TYPE( float, "%f")
DEF0TYPE( char, "%c")
/* andsoforth... */
#undef DEF0TYPE


// define the format string of a nullary function
template <class Return>
struct ToString< Return (*) () >
{
static std::string value() { return "%s()"; }
};


// unary functions
template <class Return, class T >
struct ToString< Return (*) ( T ) >
{
static std::string value() { return std::string("%s(") +
ToString<T:: value() + ")"; }
};


// binary functions
template <class Return, class T, class U >
struct ToString< Return (*) ( T , U ) >
{
static std::string value() { return std::string("%s(") +
ToString<T:: value() + ", " + ToString<U>::value() + ")"; }
};

// ternary functions
template <class Return, class T, class U, class V >
struct ToString< Return (*) ( T , U, V ) >
{
static std::string value() { return std::string("%s(") +
ToString<T:: value() + ", " + ToString<U>::value() + ", " +
ToString<V>::value() + ")"; }
};

// and so on

// a helper function, which provides a bit nicer syntax
template <class T>
std::string toString( T )
{
return ToString<T:: value();
}

// two functions
void function1( int a, double b) {}
void function2( double x, double y, char * string) {}

int main()
{
std::cout << "format string for the main function: " <<
toString( main ) << std::endl;
std::cout << "format string of 'function1' " <<
toString( function1 ) << std::endl;
std::cout << "format stirng of 'function2' " << toString( function2)
<< std::endl;
return 0;

}


This gives as output
format string for the main function: %s()
format string of 'function1' %s(%d, %f)
format stirng of 'function2' %s(%f, %f, %s)


regard,
Wijnand Suijlen

raghukumar
Guest
 
Posts: n/a
#4: Oct 16 '07

re: function trace


Well that's perfect,
Hi wijnand,
sorry if i am using your name?

I know bits and peace about template programming, if you don't mind
can you give some advice
like which book to read for good template programming. It would be
very helpful if you can
give link to any of the articles authored by you.

On Oct 16, 7:31 pm, wijnand <wijnandsuij...@gmail.comwrote:
Quote:
Is this something you can use?
>
#include <iostream>
#include <string>
>
template <class T>
struct ToString;
// keep this empty to emit a compile time error
// when it doesn't have a associated string
>
// Define the format specifiers of the basic types
#define DEF0TYPE( type, str ) \
template < \
struct ToString< type \
{ static std::string value() { return str; } \
};
>
DEF0TYPE( int, "%d" )
DEF0TYPE( double, "%f" )
DEF0TYPE( char *, "%s" )
DEF0TYPE( const char *, "%s" )
DEF0TYPE( float, "%f")
DEF0TYPE( char, "%c")
/* andsoforth... */
#undef DEF0TYPE
>
// define the format string of a nullary function
template <class Return>
struct ToString< Return (*) () >
{
static std::string value() { return "%s()"; }
>
};
>
// unary functions
template <class Return, class T >
struct ToString< Return (*) ( T ) >
{
static std::string value() { return std::string("%s(") +
ToString<T:: value() + ")"; }
>
};
>
// binary functions
template <class Return, class T, class U >
struct ToString< Return (*) ( T , U ) >
{
static std::string value() { return std::string("%s(") +
ToString<T:: value() + ", " + ToString<U>::value() + ")"; }
>
};
>
// ternary functions
template <class Return, class T, class U, class V >
struct ToString< Return (*) ( T , U, V ) >
{
static std::string value() { return std::string("%s(") +
ToString<T:: value() + ", " + ToString<U>::value() + ", " +
ToString<V>::value() + ")"; }
>
};
>
// and so on
>
// a helper function, which provides a bit nicer syntax
template <class T>
std::string toString( T )
{
return ToString<T:: value();
>
}
>
// two functions
void function1( int a, double b) {}
void function2( double x, double y, char * string) {}
>
int main()
{
std::cout << "format string for the main function: " <<
toString( main ) << std::endl;
std::cout << "format string of 'function1' " <<
toString( function1 ) << std::endl;
std::cout << "format stirng of 'function2' " << toString( function2)
<< std::endl;
return 0;
>
}
>
This gives as output
format string for the main function: %s()
format string of 'function1' %s(%d, %f)
format stirng of 'function2' %s(%f, %f, %s)
>
regard,
Wijnand Suijlen

Default User
Guest
 
Posts: n/a
#5: Oct 16 '07

re: function trace


raghukumar wrote:
Quote:
Well that's perfect,
Please don't top-post. Your replies belong following or interspersed
with properly trimmed quotes. See the majority of other posts in the
newsgroup, or the group FAQ list:
<http://www.parashift.com/c++-faq-lite/how-to-post.html>
wijnand
Guest
 
Posts: n/a
#6: Oct 16 '07

re: function trace


Hi Raghukumar,

On Oct 16, 5:15 pm, raghukumar <raghukumar.r...@gmail.comwrote:
Quote:
I know bits and peace about template programming, if you don't mind
can you give some advice like which book to read for good template
programming.
I learned it from:
C++ Template Metaprogramming
by David Abrahams and Aleksey Gurtovoy
which is a book in the C++ In-Depth Series
ISBN:0-321-22725-5

Because C++ TMP is like functional programming, I had much help from
past experience in Haskell. This language I learned from the book:

The Haskell School of Expression
by Paul Hudak
ISBN: 0-521-64408-9
Quote:
It would be very helpful if you can
give link to any of the articles authored by you.
I haven't written anything about this (yet ;-) )

Happy Meta-programming!
Wijnand Suijlen

baibaichen
Guest
 
Posts: n/a
#7: Oct 17 '07

re: function trace


Thanks, it does help me

However getting such format string is also in run time not in complie
time.

-Chang


baibaichen
Guest
 
Posts: n/a
#8: Oct 17 '07

re: function trace


On Oct 16, 10:31 pm, wijnand <wijnandsuij...@gmail.comwrote:
Quote:
Is this something you can use?
>
#include <iostream>
#include <string>
>
template <class T>
struct ToString;
// keep this empty to emit a compile time error
// when it doesn't have a associated string
>
// Define the format specifiers of the basic types
#define DEF0TYPE( type, str ) \
template < \
struct ToString< type \
{ static std::string value() { return str; } \
};
>
DEF0TYPE( int, "%d" )
DEF0TYPE( double, "%f" )
DEF0TYPE( char *, "%s" )
DEF0TYPE( const char *, "%s" )
DEF0TYPE( float, "%f")
DEF0TYPE( char, "%c")
/* andsoforth... */
#undef DEF0TYPE
>
// define the format string of a nullary function
template <class Return>
struct ToString< Return (*) () >
{
static std::string value() { return "%s()"; }
>
};
>
// unary functions
template <class Return, class T >
struct ToString< Return (*) ( T ) >
{
static std::string value() { return std::string("%s(") +
ToString<T:: value() + ")"; }
>
};
>
// binary functions
template <class Return, class T, class U >
struct ToString< Return (*) ( T , U ) >
{
static std::string value() { return std::string("%s(") +
ToString<T:: value() + ", " + ToString<U>::value() + ")"; }
>
};
>
// ternary functions
template <class Return, class T, class U, class V >
struct ToString< Return (*) ( T , U, V ) >
{
static std::string value() { return std::string("%s(") +
ToString<T:: value() + ", " + ToString<U>::value() + ", " +
ToString<V>::value() + ")"; }
>
};
>
// and so on
>
// a helper function, which provides a bit nicer syntax
template <class T>
std::string toString( T )
{
return ToString<T:: value();
>
}
>
// two functions
void function1( int a, double b) {}
void function2( double x, double y, char * string) {}
>
int main()
{
std::cout << "format string for the main function: " <<
toString( main ) << std::endl;
std::cout << "format string of 'function1' " <<
toString( function1 ) << std::endl;
std::cout << "format stirng of 'function2' " << toString( function2)
<< std::endl;
return 0;
>
}
>
This gives as output
format string for the main function: %s()
format string of 'function1' %s(%d, %f)
format stirng of 'function2' %s(%f, %f, %s)
>
regard,
Wijnand Suijlen
Thanks, it does help me.
but it's in run-time, not compile time.
Is there any imporvement?

chang

wijnand
Guest
 
Posts: n/a
#9: Oct 17 '07

re: function trace


Hi Chang,

On Oct 17, 8:29 am, baibaichen <baibaic...@gmail.comwrote:
Quote:
Thanks, it does help me.
but it's in run-time, not compile time.
Is there any imporvement?
So what you want is a string literal? The only way you can obtain
those is with the preprocessor. There you are in trouble, because the
preprocessor knows nothing about types. So, the only solution I can
think of is to build and use a small code generator to do just this.

Wijnand

raghukumar
Guest
 
Posts: n/a
#10: Oct 17 '07

re: function trace


On Oct 17, 2:06 am, wijnand <wijnandsuij...@gmail.comwrote:
thanks
Quote:
Hi Raghukumar,
>
On Oct 16, 5:15 pm, raghukumar <raghukumar.r...@gmail.comwrote:
>
Quote:
I know bits and peace about template programming, if you don't mind
can you give some advice like which book to read for good template
programming.
>
I learned it from:
C++ Template Metaprogramming
by David Abrahams and Aleksey Gurtovoy
which is a book in the C++ In-Depth Series
ISBN:0-321-22725-5
>
Because C++ TMP is like functional programming, I had much help from
past experience in Haskell. This language I learned from the book:
>
The Haskell School of Expression
by Paul Hudak
ISBN: 0-521-64408-9
>
Quote:
It would be very helpful if you can
give link to any of the articles authored by you.
>
I haven't written anything about this (yet ;-) )
>
Happy Meta-programming!
Wijnand Suijlen

Closed Thread