Is extended const common practice?

D

DeMarcus

Hi,

I'm using extended const like the following.

// ExtConst.hpp
#ifndef EXT_CONST
#define EXT_CONST

#include <string>

struct ExtConst
{
ExtConst( double value, const std::string& description )
: value(value), description(description) {}

const double value;
const std::string description;
};

#endif


// Constants.hpp
#ifndef CONSTANTS
#define CONSTANTS

#include "ExtConst.hpp"

const ExtConst PI( 3.1415, "Circumference / diameter." );
const ExtConst E( 2.71828, "Euler's constant." );

#endif

// Now I use ExtConst.hpp in several files since const in front of
ExtConst ensures internal linkage (§7.1.1/7).


// An example.
#include "Constants.hpp"

int main()
{
std::cout << "Constant: " << E.value
<< " Description: " << E.description << std::endl;
}


Are constants made up of whole classes or structures common practice? Do
you use that in your projects, and if not, is there a reason?


Thanks,
Daniel
 
D

DeMarcus

Victor said:
Actually, constants are generally not common practice, at least from
what I have been able to determine in the places where I have worked.


Constants like PI, E, are self-documenting. Constants whose source
isn't obvious usually have comments next to their definitions.

Other things, like parts of the system that don't usually change during
the run-time are most often defined in special configuration files that
are read at the run time. And in those files they are documented. The
reason is not to have to change the source code (and rebuild, etc.) when
it's determined that some constant has to be adjusted.

V

Good points.

Actually PI and E were just simple examples. My real idea is that I want
to create some form of message id that would look like this.

const MessageID( 4711, "GetStatus" );
const MessageID( 4712, "SetStatus" );

Now the integer could be used internally to avoid strcmp for performance
reasons, and the string can be used for debugging and when sending the
message over the net.

As you say, the integers are likely to change when more messages are
added, hence version problems may arise if compiled into the code.

This is just an idea in my head so far.
 
J

Jonathan Lee

My real idea is that I want
to create some form of message id that would look like this.

const MessageID( 4711, "GetStatus" );
const MessageID( 4712, "SetStatus" );

Now the integer could be used internally to avoid strcmp for performance
reasons, and the string can be used for debugging and when sending the
message over the net.

Possibly related: if you can use enums you could write a
function like:

ostream& operator<<(ostream& os, enum_type e) {
switch (e) {
case GetStatus: os << "GetStatus"; break;
case SetStatus: os << "SetStatus"; break;
// ...
}
}

Convenient for debugging, at least. I do this for error codes
sometimes, so I can write:

error_t err = compress(filename);
if (err != OK)
cout << "Error occurred: " << err << endl;

and get
"Error occurred: File not found"

--Jonathan
 
D

DeMarcus

Jonathan said:
Possibly related: if you can use enums you could write a
function like:

ostream& operator<<(ostream& os, enum_type e) {
switch (e) {
case GetStatus: os << "GetStatus"; break;
case SetStatus: os << "SetStatus"; break;
// ...
}
}

Convenient for debugging, at least. I do this for error codes
sometimes, so I can write:

error_t err = compress(filename);
if (err != OK)
cout << "Error occurred: " << err << endl;

and get
"Error occurred: File not found"

--Jonathan

Yes, thats similar to my problem. Thanks!
 
V

Victor Bazarov

[..] My real idea is that I want
to create some form of message id that would look like this.

const MessageID( 4711, "GetStatus" );
const MessageID( 4712, "SetStatus" );

I am guessing you omitted the names of the objects. Did you mean to write

const MessageID msgGetStatus(4711, "GetStatus");
const MessageID msgSetStatus(4712, "SetStatus");

?
Now the integer could be used internally to avoid strcmp for performance
reasons, and the string can be used for debugging and when sending the
message over the net.

Does the constant's value, so to speak, like 4711, get used in some form
other than just returning it from a function? I mean, PI and E are used
in expressions, where mnemonic designation is preferred over the number.
If you only use those constants to pass around, you might consider
investing in a mechanism that would translate the constant's value into
the "meaning". Then you will have a single place to provide any other
fancy processing, like translation into another language.

Take Windows applications for example. Help IDs are just numbers. Yet
there is a system that "converts" those numbers into a readable document
that a special application can display for you. The same with error
messages that are mostly identified by their, well, ID, which is, again,
just a number. The textual content is then obtained from the "resource"
system (which can actually be independently compiled and linked to the
existing executable without having to change the code).
As you say, the integers are likely to change when more messages are
added, hence version problems may arise if compiled into the code.

If you dedicate 32 bits unsigned integers to those IDs, you aren't going
to run out of numbers any time soon. Four billion is quite a number.

Learn more about what's available out there before committing to anything.

V
 
D

DeMarcus

[..] My real idea is that I want
to create some form of message id that would look like this.

const MessageID( 4711, "GetStatus" );
const MessageID( 4712, "SetStatus" );

I am guessing you omitted the names of the objects. Did you mean to write

const MessageID msgGetStatus(4711, "GetStatus");
const MessageID msgSetStatus(4712, "SetStatus");

?

Yes, of course it should be like that.
Does the constant's value, so to speak, like 4711, get used in some form
other than just returning it from a function? I mean, PI and E are used
in expressions, where mnemonic designation is preferred over the number.
If you only use those constants to pass around, you might consider
investing in a mechanism that would translate the constant's value into
the "meaning". Then you will have a single place to provide any other
fancy processing, like translation into another language.

My idea was that the number 4711 should be used for fast lookups
internally, e.g.

switch( msgId )
{
case 4711: getStatus(); break;
case 4712: setStatus(); break;
}

while the string GetStatus could be used when communicating with other
systems externally where numbers ain't that descriptive.

Having a translation mechanism as you describe is definitely one way to
solve it, however, my main reason to put the number and string at the
same place is that the string must always be provided and cannot be
forgotten.

Take Windows applications for example. Help IDs are just numbers. Yet
there is a system that "converts" those numbers into a readable document
that a special application can display for you. The same with error
messages that are mostly identified by their, well, ID, which is, again,
just a number. The textual content is then obtained from the "resource"
system (which can actually be independently compiled and linked to the
existing executable without having to change the code).


If you dedicate 32 bits unsigned integers to those IDs, you aren't going
to run out of numbers any time soon. Four billion is quite a number.

Yes, but I remember in one application we had enums like this.

enum Commands
{
STATUS_COMMANDS_BEGIN = 100,
STATUS_GET_CPU_LOAD = 101,
STATUS_GET_DISK_SPACE = 102,
...
STATUS_COMMANDS_END = 150,

...
}

Then we could route commands depending on category, e.g.

if( msgID > STATUS_COMMAND_BEGIN && msgID < STATUS_COMMAND_END )
processStatus( msgID );

Even though 32 bits is enough, there is a possibility that
STATUS_COMMANDS_END needs to be extended to 151 or 200 one day.
Learn more about what's available out there before committing to anything.

V

I'm trying to find as many implementations I can. I've been looking into
SOAP and CORBA but it's difficult to find examples focusing on the pros
and cons of using different implementations of message IDs or IDs in
general.
 

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,262
Messages
2,571,045
Members
48,769
Latest member
Clifft

Latest Threads

Top