D
deathwillendthiswar
Hi,
I'm not too keen on variable argument lists, but I'd like to use them
for some logging functions.
Suppose the prototype for logging functions is
void Log( const String& sMessage, const int iLevel, const bool
bUseLineEnd );
String already takes variable argument lists in it's sPrintf function,
which also returns a reference to this, so I could use
Log( String().sPrintf( "test %d", 5 ), level, true ); for example.
That's not really a problem, but what happens: String is constructed,
then allocates memory, then calls sprintf and returns a reference to
itself. Internally, Log copies the memory from String into pre-
allocated space. The call returns, and String and it's memory are
deallocated.
What I would rather like to see, is that the sprintf call happens
directly on the pre-allocated memory in Log. That saves allocating,
memcpy and deallocation. However, I would also like to keep the same
prototype, so that I can use Log( "test %d", 5, level, true );
Variable arguments can't be listed first, so my first thought was to
simply declare all possible functions:
template< class T0 >
void Log( const char* Format, const T0 arg0, const int iLevel, const
bool bLineEnd );
template< class T0, class T1 >
void Log( const char* Format, const T0 arg0, const T1 arg1, const int
iLevel, const bool bLineEnd );
and so on.
Implementating this was easy at first sight: let the Logger class have
a method that accepts a va_list and construct the list from the
arguments.
template< class T0 >
void Log( const char* Format, const T0 arg0, const int iLevel, const
bool bLineEnd )
{
va_list args;
va_start( args, Format );
InternalLogFunction( Format, args, iLevel, bLineEnd );
va_end( args );
}
This does excatly what I want, though it's not overly pretty, but gcc
(4.1.2) chokes on this saying "va_start used in function with fixed
args".
I don't really understand why it is not allowed (afaik va_start just
lets args point to the next element on the stack, arg0 in this case),
can someone explain this?
Also, what would be other ways to achieve this? What I basically want
is a variable argument list of some kind, followed by 2 named
parameters. (ok I could just use Log( const int, const bool, const
char*, ... ) but it would just make writing much easier if it behaved
like the non-printf Log)
Thanks!
I'm not too keen on variable argument lists, but I'd like to use them
for some logging functions.
Suppose the prototype for logging functions is
void Log( const String& sMessage, const int iLevel, const bool
bUseLineEnd );
String already takes variable argument lists in it's sPrintf function,
which also returns a reference to this, so I could use
Log( String().sPrintf( "test %d", 5 ), level, true ); for example.
That's not really a problem, but what happens: String is constructed,
then allocates memory, then calls sprintf and returns a reference to
itself. Internally, Log copies the memory from String into pre-
allocated space. The call returns, and String and it's memory are
deallocated.
What I would rather like to see, is that the sprintf call happens
directly on the pre-allocated memory in Log. That saves allocating,
memcpy and deallocation. However, I would also like to keep the same
prototype, so that I can use Log( "test %d", 5, level, true );
Variable arguments can't be listed first, so my first thought was to
simply declare all possible functions:
template< class T0 >
void Log( const char* Format, const T0 arg0, const int iLevel, const
bool bLineEnd );
template< class T0, class T1 >
void Log( const char* Format, const T0 arg0, const T1 arg1, const int
iLevel, const bool bLineEnd );
and so on.
Implementating this was easy at first sight: let the Logger class have
a method that accepts a va_list and construct the list from the
arguments.
template< class T0 >
void Log( const char* Format, const T0 arg0, const int iLevel, const
bool bLineEnd )
{
va_list args;
va_start( args, Format );
InternalLogFunction( Format, args, iLevel, bLineEnd );
va_end( args );
}
This does excatly what I want, though it's not overly pretty, but gcc
(4.1.2) chokes on this saying "va_start used in function with fixed
args".
I don't really understand why it is not allowed (afaik va_start just
lets args point to the next element on the stack, arg0 in this case),
can someone explain this?
Also, what would be other ways to achieve this? What I basically want
is a variable argument list of some kind, followed by 2 named
parameters. (ok I could just use Log( const int, const bool, const
char*, ... ) but it would just make writing much easier if it behaved
like the non-printf Log)
Thanks!