[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

creating unique message identifiers

mliptak

11/4/2008 10:54:00 AM

I'm trying to implement logging in my application, so that each log
message has its unique identifier, e.g.
log(identifier, text)
What I want to achieve is that the compiler screams if the log() with
'identifier' is also used in some other place in the code which would
make the 'identifier' not unique.
Is that something that can be achieved in C++?
Thanks
15 Answers

James Kanze

11/4/2008 1:22:00 PM

0

On Nov 4, 11:54 am, mliptak <Meht...@gmail.com> wrote:
> I'm trying to implement logging in my application, so that
> each log message has its unique identifier, e.g.
> log(identifier, text)
> What I want to achieve is that the compiler screams if the
> log() with 'identifier' is also used in some other place in
> the code which would make the 'identifier' not unique.
> Is that something that can be achieved in C++?

It depends on the type of identifier, but in general, yes,
provided log is a macro. In the general case, you need a local
static variable to achieve it, and the actual identifier won't
be known until compile time. If identifier is text, however,
you can generate it with a macro using __FILE__ and __LINE__.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

mliptak

11/4/2008 1:31:00 PM

0

On Nov 4, 2:21 pm, James Kanze <james.ka...@gmail.com> wrote:
> On Nov 4, 11:54 am, mliptak <Meht...@gmail.com> wrote:
>
> > I'm trying to implement logging in my application, so that
> > each log message has its unique identifier, e.g.
> > log(identifier, text)
> > What I want to achieve is that the compiler screams if the
> > log() with 'identifier' is also used in some other place in
> > the code which would make the 'identifier' not unique.
> > Is that something that can be achieved in C++?
>
> It depends on the type of identifier, but in general, yes,
> provided log is a macro.  In the general case, you need a local
> static variable to achieve it, and the actual identifier won't
> be known until compile time.  If identifier is text, however,
> you can generate it with a macro using __FILE__ and __LINE__.

What if I want to set the identifier myself, not have it generated at
compile time (using local static variable)?

I was also thinking of using the __FILE__ and __LINE__ but the problem
is this could change when the code changes, and I need to have the
identifier fixed for each message.

Victor Bazarov

11/4/2008 1:54:00 PM

0

mliptak wrote:
> On Nov 4, 2:21 pm, James Kanze <james.ka...@gmail.com> wrote:
>> On Nov 4, 11:54 am, mliptak <Meht...@gmail.com> wrote:
>>
>>> I'm trying to implement logging in my application, so that
>>> each log message has its unique identifier, e.g.
>>> log(identifier, text)
>>> What I want to achieve is that the compiler screams if the
>>> log() with 'identifier' is also used in some other place in
>>> the code which would make the 'identifier' not unique.
>>> Is that something that can be achieved in C++?
>>
>> It depends on the type of identifier, but in general, yes,
>> provided log is a macro. In the general case, you need a local
>> static variable to achieve it, and the actual identifier won't
>> be known until compile time. If identifier is text, however,
>> you can generate it with a macro using __FILE__ and __LINE__.
>
> What if I want to set the identifier myself, not have it generated at
> compile time (using local static variable)?
>
> I was also thinking of using the __FILE__ and __LINE__ but the problem
> is this could change when the code changes, and I need to have the
> identifier fixed for each message.

I think you're still to figure out exactly what you need (i.e. the
"requirements" part of your design). What does it mean "to have the
identifier fixed for each message"? Do you intend to have the same
message sprinkled throughout your code and have the same identifier
accompany it? If the messages are unique, why nave an identifier at
all? If the messages aren't unique and can be the same, using the
exact location in your code to generate the identifier is a nice way
to ensure uniqueness of them.

The presence of __FILE__ and __LINE__ is very convenient if you need
to later find which of the millions of lines in your code caused the
output of the message.

Another way would be a global counter of sorts. You could create
a class that when instantiated would increment some counter and when
output would produce that counter (which it would keep as a static
data member), but then you lose control over what counter relates to
which line since generation of the counter can depend on the execution
order of the constructors for those objects.

Go with __FILE__ and __LINE__. Trust us, we've done it before.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


Maxim Yegorushkin

11/4/2008 1:55:00 PM

0

On Nov 4, 10:54 am, mliptak <Meht...@gmail.com> wrote:
> I'm trying to implement logging in my application, so that each log
> message has its unique identifier, e.g.
> log(identifier, text)

What do you need that identifier for?

> What I want to achieve is that the compiler screams if the log() with
> 'identifier' is also used in some other place in the code which would
> make the 'identifier' not unique.

It is not possible in the general case when a binary is built by
linking several object files compiled separately. In this case you
could make the linker produce an error, however, it still would not be
possible in the presence of dynamic libraries.

--
Max

mliptak

11/4/2008 2:05:00 PM

0

On Nov 4, 2:53 pm, "Victor Bazarov" <v.Abaza...@comAcast.net> wrote:
> mliptak wrote:
> > On Nov 4, 2:21 pm, James Kanze <james.ka...@gmail.com> wrote:
> >> On Nov 4, 11:54 am, mliptak <Meht...@gmail.com> wrote:
>
> >>> I'm trying to implement logging in my application, so that
> >>> each log message has its unique identifier, e.g.
> >>> log(identifier, text)
> >>> What I want to achieve is that the compiler screams if the
> >>> log() with 'identifier' is also used in some other place in
> >>> the code which would make the 'identifier' not unique.
> >>> Is that something that can be achieved in C++?
>
> >> It depends on the type of identifier, but in general, yes,
> >> provided log is a macro. In the general case, you need a local
> >> static variable to achieve it, and the actual identifier won't
> >> be known until compile time. If identifier is text, however,
> >> you can generate it with a macro using __FILE__ and __LINE__.
>
> > What if I want to set the identifier myself, not have it generated at
> > compile time (using local static variable)?
>
> > I was also thinking of using the __FILE__ and __LINE__ but the problem
> > is this could change when the code changes, and I need to have the
> > identifier fixed for each message.
>
> I think you're still to figure out exactly what you need (i.e. the
> "requirements" part of your design).  What does it mean "to have the
> identifier fixed for each message"?  Do you intend to have the same
> message sprinkled throughout your code and have the same identifier
> accompany it?  If the messages are unique, why nave an identifier at
> all?  If the messages aren't unique and can be the same, using the
> exact location in your code to generate the identifier is a nice way
> to ensure uniqueness of them.

What I meant by this is to have the "code" associated with particular
"text" and this association never changes (which is not true if I'd be
using __FILE__ and __LINE__).

You asked why have identifier at all.. Well another requirement is to
have the "code" unique throughout the program.

Example:

// a.cc
// ok
log(code1, "text1");
log(code2, "text2");
....
// invalid - code1 already used before
log(code1, "text3");

// b.cc
// invalid - code1 already used elsewhere
log(code1, "text4");
// ok
log(code4, "text5");

>
> The presence of __FILE__ and __LINE__ is very convenient if you need
> to later find which of the millions of lines in your code caused the
> output of the message.
>
> Another way would be a global counter of sorts.  You could create
> a class that when instantiated would increment some counter and when
> output would produce that counter (which it would keep as a static
> data member), but then you lose control over what counter relates to
> which line since generation of the counter can depend on the execution
> order of the constructors for those objects.
>

As I mentioned before, the disadvantage of this approach is that the
codes of messages change when the source changes.

> Go with __FILE__ and __LINE__.  Trust us, we've done it before.
>
> V

mliptak

11/4/2008 2:12:00 PM

0

On Nov 4, 2:54 pm, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
wrote:
> On Nov 4, 10:54 am, mliptak <Meht...@gmail.com> wrote:
>
> > I'm trying to implement logging in my application, so that each log
> > message has its unique identifier, e.g.
> > log(identifier, text)
>
> What do you need that identifier for?

The requirement is to have the log messages searchable easily, by
tools like grep. It is a bit more convenient than search by message
text.

>
> > What I want to achieve is that the compiler screams if the log() with
> > 'identifier' is also used in some other place in the code which would
> > make the 'identifier' not unique.
>
> It is not possible in the general case when a binary is built by
> linking several object files compiled separately. In this case you
> could make the linker produce an error, however, it still would not be
> possible in the presence of dynamic libraries.

Yes, I thought about the dynamic libraries before. In my case it is
ok if it does not work for dynamic libraries as I don't use them right
now.

>
> --
> Max

Hendrik Schober

11/4/2008 2:49:00 PM

0

mliptak wrote:
> On Nov 4, 2:21 pm, James Kanze <james.ka...@gmail.com> wrote:
>> On Nov 4, 11:54 am, mliptak <Meht...@gmail.com> wrote:
>>
>>> I'm trying to implement logging in my application, so that
>>> each log message has its unique identifier, e.g.
>>> log(identifier, text)
>>> What I want to achieve is that the compiler screams if the
>>> log() with 'identifier' is also used in some other place in
>>> the code which would make the 'identifier' not unique.
>>> Is that something that can be achieved in C++?
>> It depends on the type of identifier, but in general, yes,
>> provided log is a macro. In the general case, you need a local
>> static variable to achieve it, and the actual identifier won't
>> be known until compile time. If identifier is text, however,
>> you can generate it with a macro using __FILE__ and __LINE__.
>
> What if I want to set the identifier myself, not have it generated at
> compile time (using local static variable)?
>
> I was also thinking of using the __FILE__ and __LINE__ but the problem
> is this could change when the code changes, and I need to have the
> identifier fixed for each message.

Why don't you want to use '__FILE__' and '__LINE__'? If these
change too often, add '__DATE__' and '__TIME__' which, together
with your version management should be enough.
OTOH, I have written a logging library which allows grouping of
code and which emits the group's tag name. You can have a look
at that at http://sourceforge.net/project.... (The main
goal of this was to use expression templates to gain performance
when logging is turned off and I haven't found the time yet to
document anything, so I apologize if it seems a bit cryptic.)

HTH,

Schobi

mliptak

11/4/2008 2:59:00 PM

0

On Nov 4, 3:48 pm, Hendrik Schober <spamt...@gmx.de> wrote:
> mliptak wrote:
> > On Nov 4, 2:21 pm, James Kanze <james.ka...@gmail.com> wrote:
> >> On Nov 4, 11:54 am, mliptak <Meht...@gmail.com> wrote:
>
> >>> I'm trying to implement logging in my application, so that
> >>> each log message has its unique identifier, e.g.
> >>> log(identifier, text)
> >>> What I want to achieve is that the compiler screams if the
> >>> log() with 'identifier' is also used in some other place in
> >>> the code which would make the 'identifier' not unique.
> >>> Is that something that can be achieved in C++?
> >> It depends on the type of identifier, but in general, yes,
> >> provided log is a macro.  In the general case, you need a local
> >> static variable to achieve it, and the actual identifier won't
> >> be known until compile time.  If identifier is text, however,
> >> you can generate it with a macro using __FILE__ and __LINE__.
>
> > What if I want to set the identifier myself, not have it generated at
> > compile time (using local static variable)?
>
> > I was also thinking of using the __FILE__ and __LINE__ but the problem
> > is this could change when the code changes, and I need to have the
> > identifier fixed for each message.
>
>   Why don't you want to use '__FILE__' and '__LINE__'? If these
>   change too often, add '__DATE__' and '__TIME__' which, together
>   with your version management should be enough.

I think it is too complicated for what I really need to achieve.
What I had in mind originally was something like:

log(ERROR01, "Text of error 1");
log(ERROR02, "Text of error 2");

>   OTOH, I have written a logging library which allows grouping of
>   code and which emits the group's tag name. You can have a look
>   at that athttp://sourceforge.net/project.... (The main
>   goal of this was to use expression templates to gain performance
>   when logging is turned off and I haven't found the time yet to
>   document anything, so I apologize if it seems a bit cryptic.)
>
>   HTH,
>
>   Schobi

Bart van Ingen Schenau

11/4/2008 4:15:00 PM

0

On Nov 4, 3:05 pm, mliptak <Meht...@gmail.com> wrote:
>
> What I meant by this is to have the "code" associated with particular
> "text" and this association never changes (which is not true if I'd be
> using __FILE__ and __LINE__).
>
> You asked why have identifier at all.. Well another requirement is to
> have the "code" unique throughout the program.
>
> Example:
>
> // a.cc
> // ok
> log(code1, "text1");
> log(code2, "text2");
> ...
> // invalid - code1 already used before
> log(code1, "text3");

If that line had read
log(code1, "text1"),
would that have been OK?

>
> // b.cc
> // invalid - code1 already used elsewhere
> log(code1, "text4");
> // ok
> log(code4, "text5");
>

If you want to have a consistent mapping between a numeric/symbolic ID
and a string, the worst thing you can do is require the programmer to
provide both the ID and the string.

The solution I would propose is to use only the ID in the log
statements, and use a separate mechanism (for example a table) to map
the ID to a string.
For example, something like this:

enum logID {
code1,
code2,
code4
};

char const * const logString[] = {
"text1",
"text2",
"text5"
};

void log(enum logID id)
{
char const * const text = logString[id];
// write text to log destination
}
//usage: log(code1);

To keep the mapping between the ID's and the texts consistent, you can
generate the enumeration and the table from a single source. This
could even be done with the preprocessor.

Bart v Ingen Schenau

peter koch

11/4/2008 6:27:00 PM

0

On 4 Nov., 15:59, mliptak <Meht...@gmail.com> wrote:
> On Nov 4, 3:48 pm, Hendrik Schober <spamt...@gmx.de> wrote:
>
>
>
>
>
> > mliptak wrote:
> > > On Nov 4, 2:21 pm, James Kanze <james.ka...@gmail.com> wrote:
> > >> On Nov 4, 11:54 am, mliptak <Meht...@gmail.com> wrote:
>
> > >>> I'm trying to implement logging in my application, so that
> > >>> each log message has its unique identifier, e.g.
> > >>> log(identifier, text)
> > >>> What I want to achieve is that the compiler screams if the
> > >>> log() with 'identifier' is also used in some other place in
> > >>> the code which would make the 'identifier' not unique.
> > >>> Is that something that can be achieved in C++?
> > >> It depends on the type of identifier, but in general, yes,
> > >> provided log is a macro.  In the general case, you need a local
> > >> static variable to achieve it, and the actual identifier won't
> > >> be known until compile time.  If identifier is text, however,
> > >> you can generate it with a macro using __FILE__ and __LINE__.
>
> > > What if I want to set the identifier myself, not have it generated at
> > > compile time (using local static variable)?
>
> > > I was also thinking of using the __FILE__ and __LINE__ but the problem
> > > is this could change when the code changes, and I need to have the
> > > identifier fixed for each message.
>
> >   Why don't you want to use '__FILE__' and '__LINE__'? If these
> >   change too often, add '__DATE__' and '__TIME__' which, together
> >   with your version management should be enough.
>
> I think it is too complicated for what I really need to achieve.
> What I had in mind originally was something like:
>
> log(ERROR01, "Text of error 1");
> log(ERROR02, "Text of error 2");
>

Certainly, if you search for simplicity using __FILE__ and __LINE__ is
the way to go. I once used your approach (manually and written in C
loads of years ago), but the reason not to use __LINE__ and __FILE__
was because of a restricted environment where low space overhead was
at a premium. (It was not for logging but for assertions, and in case
of an assert, the integer id was simply dumped).

/Peter