logging function

M

Martin

I am actually more concerned about whether the code might be broken. Is
it
legal to write to a temporary stringstream?

i dont know why it should not be legal...but i think your destructor
should be virtual. dont know if that solves the problem though.
(no time for testing it yet...).
otherwise, the approach of deriving from stringstream looks very
promising to me (cause it's very straightforward compared to what
i currently do, define my own streambuf).

br
martin
 
D

Dietmar Kuehl

Martin said:
rlog is now a macro defined as
#define rlog (rlog_ostream<<"<"__FUNCTION__">")
so it'll log the caller's function name automatically.
how would i do that ? i thought about locking a mutex in the macro
somehow, but then it cant be released after the logging is completed.

Why not? What is wrong with this:

#define rlog (lock(), (rlog_ostraem << "<" __FUNCTION__ ">"))

where 'lock' is defined as

struct lock {
lock() { thread_lock_mutex(rlog_mutex); }
~lock() { thread_unlock_mutex(rlog_mutex): }
private:
lock(lock const&);
void operator= (lock const&);
};

The temporary created by 'lock()' is destructed at the end of the
"full expression" and the comma operator guarantees the appropriate
order of execution.
 
K

Kai-Uwe Bux

Rob said:
Kai-Uwe Bux wrote in in
comp.lang.c++:



Such identifiers are reserved *everywhere*, you may not use them,
at least if you want to call your code C++.

Identifiers with a *single* leading underscore can be used as you
describe.

HTH.

Rob.

Thanks,


I will change my namespace to DO_NOT_USE:: (for want of a better name)
before I start advertising my code as C++.


Best regards

Kai-Uwe
 
M

Martin

Why not? What is wrong with this:

#define rlog (lock(), (rlog_ostraem << "<" __FUNCTION__ ">"))

very cool! i didnt know that would work! thanks a lot...for me this
is by far the easiert solution!

br
martin
 
K

Kai-Uwe Bux

Martin said:
i dont know why it should not be legal...but i think your destructor
should be virtual. dont know if that solves the problem though.
(no time for testing it yet...).
otherwise, the approach of deriving from stringstream looks very
promising to me (cause it's very straightforward compared to what
i currently do, define my own streambuf).

br
martin

Hi,

the destructor should be virtual by default:

a) the class derives from std::stringstream
b) std::stringstream derives from std::basic_iostream<char>
c) basic_iostream<char> has a virtual destructor.

I slept on it, and now I think the code is fine, asside from the __xxx type
identifiers that I put in. As other posters pointed out, they are not
standard and may cause trouble. (After all, as I have learned, the
implemetation is free to whatever macromagic it sees fit with "__".)


Kai-Uwe
 
L

Luther Baker

Kai-Uwe Bux said:
Thanks,

Yes it looks ugly, and I am fully aware that these identifiers are
reserved. When I commited this code to my little private library, I put it
within a different namespace. The reason that I use ugly __xxx type
identifiers sometimes, is to remind myself that these are *not* supposed to
show up in any other file that I write. In fact, I have a __:: namespace
for that purpose. (And no, it does not reside directly within the global
namespace.)

Since the __XXX syntax is reserved, what if the compiler defined away
someting you depended on?

What if the compiler defined this?

#define __Logger __ProprietaryLogger

I don't think it is necessarily a namespace problem. The double
underscore prefix is reserved and if you use it, I think you're
susceptible to undefined behavior.

By the way, excellent thread.

-Luther
 
D

Dietmar Kuehl

Martin said:
(cause it's very straightforward compared to what
i currently do, define my own streambuf).

Defining your own streambuf for things like this is right approach!
Don't change that.
 
K

Kai-Uwe Bux

Luther said:
Since the __XXX syntax is reserved, what if the compiler defined away
someting you depended on?

What if the compiler defined this?

#define __Logger __ProprietaryLogger

I don't think it is necessarily a namespace problem. The double
underscore prefix is reserved and if you use it, I think you're
susceptible to undefined behavior.

By the way, excellent thread.

-Luther

You are right. Other posters have commented on that too. So here is a
version that is *not* vulnerable in this way:

#include <pthread.h>
#include <sstream>
#include <iostream>

void do_whatever_you_want( std::string str ) {
std::cerr << str;
}

namespace DO_NOT_USE {

static pthread_mutex_t logger_lock = PTHREAD_MUTEX_INITIALIZER;

class Logger : public std::stringstream {
public:

~Logger ( void ) {
pthread_mutex_lock( &logger_lock );
do_whatever_you_want( this->str() );
pthread_mutex_unlock( &logger_lock );
}

}; // class Logger

} // namespace DO_NOT_USE

#define rlog ( DO_NOT_USE::Logger() << std::dec << __FILE__ << " [" <<
__LINE__ << "]: " )

int main ( void ) {
rlog << "hello world!" << std::endl;
}


There is but one thing that I still do not understand: If I leave out the
sneaky std::dec in the macro definition, I see the address of the const
char * that __FILE__ expands to instead of the file name. Does someone know
why this is?


Best regards

Kai-Uwe
 

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
474,170
Messages
2,570,925
Members
47,464
Latest member
Bobbylenly

Latest Threads

Top