473,386 Members | 1,867 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

creating unique message identifiers

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
Nov 4 '08 #1
13 3675
On Nov 4, 11:54 am, mliptak <Meht...@gmail.comwrote:
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:ja*********@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

Nov 4 '08 #2
On Nov 4, 2:21*pm, James Kanze <james.ka...@gmail.comwrote:
On Nov 4, 11:54 am, mliptak <Meht...@gmail.comwrote:
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.
Nov 4 '08 #3
On Nov 4, 10:54*am, mliptak <Meht...@gmail.comwrote:
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
Nov 4 '08 #4
On Nov 4, 2:54*pm, Maxim Yegorushkin <maxim.yegorush...@gmail.com>
wrote:
On Nov 4, 10:54*am, mliptak <Meht...@gmail.comwrote:
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
Nov 4 '08 #5
mliptak wrote:
On Nov 4, 2:21 pm, James Kanze <james.ka...@gmail.comwrote:
>On Nov 4, 11:54 am, mliptak <Meht...@gmail.comwrote:
>>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/projects/templog/. (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
Nov 4 '08 #6
On Nov 4, 3:48*pm, Hendrik Schober <spamt...@gmx.dewrote:
mliptak wrote:
On Nov 4, 2:21 pm, James Kanze <james.ka...@gmail.comwrote:
On Nov 4, 11:54 am, mliptak <Meht...@gmail.comwrote:
>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/projects/templog/. (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
Nov 4 '08 #7
On Nov 4, 3:05 pm, mliptak <Meht...@gmail.comwrote:
>
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
Nov 4 '08 #8
On 4 Nov., 15:59, mliptak <Meht...@gmail.comwrote:
On Nov 4, 3:48*pm, Hendrik Schober <spamt...@gmx.dewrote:


mliptak wrote:
On Nov 4, 2:21 pm, James Kanze <james.ka...@gmail.comwrote:
>On Nov 4, 11:54 am, mliptak <Meht...@gmail.comwrote:
>>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
Nov 4 '08 #9
On Nov 4, 5:15*pm, Bart van Ingen Schenau
<Bart.van.Ingen.Sche...@ict.nlwrote:
On Nov 4, 3:05 pm, mliptak <Meht...@gmail.comwrote:


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
Yes, I was thinking about this, but the problem is the "text" is not
only a text, but string with parameters, either:
"text param %d, %s", a, b
or:
"text param " << a << ", " << b

I think I will end up with:
void log(enum logID id, ...)
{
}
and do the vsnprintf() magic in there.
Nov 5 '08 #10
On Nov 4, 2:31 pm, mliptak <Meht...@gmail.comwrote:
On Nov 4, 2:21 pm, James Kanze <james.ka...@gmail.comwrote:
On Nov 4, 11:54 am, mliptak <Meht...@gmail.comwrote:
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)?
You mean that you want the user to provide an indentifier, that
the compiler checks for uniqueness? The compiler can't do that
per se (at least not within a single statement), but you could
easily use it as the initializer of a local static variable,
which would check for uniqueness at runtime.
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.
The real question is what the identifier is to be used for.
Most of the time, if you need each point of invocation to have a
separate identifier, it is for some sort of tracing or
debugging, in which case, __FILE__ and __LINE__ are far more
useful than anything else you could come up with.

--
James Kanze (GABI Software) email:ja*********@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
Nov 5 '08 #11
On Nov 4, 3:05 pm, mliptak <Meht...@gmail.comwrote:
On Nov 4, 2:53 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
mliptak wrote:
On Nov 4, 2:21 pm, James Kanze <james.ka...@gmail.comwrote:
>On Nov 4, 11:54 am, mliptak <Meht...@gmail.comwrote:
>>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__).
Aha. Something like errno. Or the error codes returned by
Internet message protocols (smtp, nntp, http...).

That really requires an external registry. The simplest
solution is to maintain a list of code/message pairs, use it to
generate a mapping function, and just pass the code to log
(which uses the mapping function to obtain the message).

--
James Kanze (GABI Software) email:ja*********@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
Nov 5 '08 #12
On Nov 5, 6:49 am, mliptak <Meht...@gmail.comwrote:
On Nov 4, 5:15 pm, Bart van Ingen Schenau
<Bart.van.Ingen.Sche...@ict.nlwrote:
On Nov 4, 3:05 pm, mliptak <Meht...@gmail.comwrote:
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.
Yes, I was thinking about this, but the problem is the "text"
is not only a text, but string with parameters, either:
"text param %d, %s", a, b
or:
"text param " << a << ", " << b
I think I will end up with:
void log(enum logID id, ...)
{}
and do the vsnprintf() magic in there.
That's a good recepe for program crashes down the line. In such
cases, the usual solution is for log to return an output stream
wrapper (or even an ostream&, if you don't have to worry about
threading), log inserts the header text (the code, plus anything
you've already mapped), and the client appends the rest.

--
James Kanze (GABI Software) email:ja*********@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
Nov 5 '08 #13
mliptak <Me*****@gmail.comkirjutas:
On Nov 4, 2:21*pm, James Kanze <james.ka...@gmail.comwrote:
>On Nov 4, 11:54 am, mliptak <Meht...@gmail.comwrote:
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 have had a similar need sometimes - need to attach unique identifiers
to error messages which could be searched for in the source code later,
if necessary. As I have been too lazy to implement any kind of registry
or something, I have just entered the identifier by hand. If the error is
originally generated e.g. at line 345 of image_processing.cpp, I would
have used an identifier like "IMPR345". Over time the code moves to
another line, and there might be another source file with similar name,
etc., but I have actually not encountered any collisions so far. To
reduce the collision probability one could also encode current year/month
in the identifier.

Paavo


Nov 6 '08 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Louis Frolio | last post by:
Greetings All, I have read many upon many articles here regarding GUID data types and uniqueness. There have been many opinions regarding the effectiveness of GUID's and when they should/should...
3
by: Kilroy Programmer | last post by:
Is there a way to store a unique numeric identifier (say, for example, an int) into a TreeNode, so that when the TreeNode is checked (since CheckBoxes is enabled) the eventhandler AfterCheck() can...
9
by: dave m | last post by:
I need to be able to retrieve a unique ID from a users PC. I needs to be something a user could not easily change, like the computer name. Could someone point me in the right direction to find ...
9
by: crescent_au | last post by:
Hi everybody, I want to create dynamic breadcrumbs for a site I am developing. I just want to get some views about the algorithm of breadcrumbs. The way I look at it is the concept of parent/...
2
by: sammy | last post by:
If I want to return only unique values from an attribute in a table, how would I do so? The attribute may repeat across rows.
3
by: RGow | last post by:
Hi all, I need to get a unique identifier for tables created in DB2 v8.1. I can't use the table name because I want to use the identifier as part of a trigger name and the table names are...
1
by: Danny Liberty | last post by:
I need some opionions on an issue here... Suppose I want to keep a collection of objects, each need to be uniquely identified by a number. This number has no meaning as long as it's unique, so it...
4
by: ba.hons | last post by:
Hello all, Was wondering if anyone could provide some info on what could be a possible solution to a problem am having. I have to generate a Unique Identifier in C# which I will use to assign...
2
by: prasannas | last post by:
what is the difference between unique constraint and primarykey and identifiers?
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.