can the pre-processor convert string literals into chars?

S

steve.lorimer

Hi

Thanks for taking the time to read this.

I'm looking for a pre-processor command that will allow me to resolve
const
strings into const char literals at compile time.

Looking at the code below, I can take 5 characters and create a const
uint64_t value at compile time.
I can then create a switch statement that has these const values as
the
various cases.
Since each case resolves to an integer constant value at compile
time,
this switch statement is valid.

const uint64_t val1 = (static_cast<uint64_t>('S') << 32) | // S
(static_cast<uint64_t>('T') << 24) | // T
(static_cast<uint64_t>('A') << 16) | // A
(static_cast<uint64_t>('R') << 8) | // R
(static_cast<uint64_t>('T')); // T

const char c1 = 'S', c2 = 'T', c3 = 'O', c4 = 'P';
const uint64_t val2 = (static_cast<uint64_t>(c1) << 32) | // S
(static_cast<uint64_t>(c2) << 24) | // T
(static_cast<uint64_t>(c3) << 16) | // O
(static_cast<uint64_t>(c4) << 8) | // P
(static_cast<uint64_t>(0));

uint64_t input = 0;
switch (input)
{
case val1: printf("input=val1\n"); break;
case val2: printf("input=val2\n"); break;
default: break;
}
//--------------------------------------------------------------------------

Now I attempt to repeat the above code, but instead of using literal
character
values, I use a const string literal.
gcc returns the following error:

error: case label does not reduce to an integer constant

So I guess the compiler is not able to resolve the index into the char
array at compile time.


const char* const str1 = "START";
const uint64_t val1 = (static_cast<uint64_t>(str1[0]) << 32) | //
S
(static_cast<uint64_t>(str1[1]) << 24) | //
T
(static_cast<uint64_t>(str1[2]) << 16) | //
A
(static_cast<uint64_t>(str1[3]) << 8) | //
R
(static_cast<uint64_t>(str1[4])); //
T

const char* const str2 = "STOP";
const uint64_t val2 = (static_cast<uint64_t>(str2[0]) << 32) | //
S
(static_cast<uint64_t>(str2[1]) << 24) | //
T
(static_cast<uint64_t>(str2[2]) << 16) | //
O
(static_cast<uint64_t>(str2[3]) << 8) | //
P
(static_cast<uint64_t>(str2[4]));

uint64_t input = 0;
switch (input)
{
case val1: printf("input=val1\n"); break;
case val2: printf("input=val2\n"); break;
default: break;
}
//--------------------------------------------------------------------------

What I actually have is a text file containing many unique input
strings,
each a maximum of 5 characters long.
Each of these input strings has a corresponding name and a value that
it maps to. I'd like to be able to create a switch statement with a
case for each of the
possible input strings which returns the associated value.
At run-time, I can create a uint64_t value from any 5 character input
string and run the value through my case statement to get a return
value. Obviously performance wise this is far better than:
if (strncmp(...))
return ...
else
if (strncmp(...))
return ...
else
ad infinitum


Please see my example data below:

<< input_values.txt >>
MACRO1(DO_START, "START", enum_val_start)
MACRO1(DO_STOP, "STOP", enum_val_stop)

// create const values
#undef MACRO1
#define MACRO1(NAME, INPUT, VALUE) \
const uint64_t val_##NAME = (static_cast<uint64_t>(INPUT[0])
<< 32) | \
(static_cast<uint64_t>(INPUT[1])
<< 24) | \
(static_cast<uint64_t>(INPUT[2])
<< 16) | \
(static_cast<uint64_t>(INPUT[3])
<< 8) | \
(static_cast<uint64_t>(INPUT[4]));
#include "input_values.txt"

// create switch statement containing above const values
#undef MACRO1
#define MACRO1(NAME, INPUT, VALUE) \
case val_##NAME: return VALUE;

switch (val)
{
#include "input_value.txt"
default: break;
}
//--------------------------------------------------------------------------

TIA for your help
 
J

Jack Klein

Hi

Thanks for taking the time to read this.

I would have thanked you for not posting it multiple times, but oops!,
you did.

And then you waste time and bandwidth arguing with someone who
responds to you because "every microsecond counts", and you complain
you can't test your claims about relative efficiency because it's too
hard to manually build code the way you want to.

You want something like this:
const uint64_t val1 = (static_cast<uint64_t>('S') << 32) | // S
(static_cast<uint64_t>('T') << 24) | // T
(static_cast<uint64_t>('A') << 16) | // A
(static_cast<uint64_t>('R') << 8) | // R
(static_cast<uint64_t>('T')); // T

[snip]

From this:
Now I attempt to repeat the above code, but instead of using literal
character
values, I use a const string literal.
gcc returns the following error:

error: case label does not reduce to an integer constant

So I guess the compiler is not able to resolve the index into the char
array at compile time.

const char* const str1 = "START";
const uint64_t val1 = (static_cast<uint64_t>(str1[0]) << 32) | //
S
(static_cast<uint64_t>(str1[1]) << 24) | //
T
(static_cast<uint64_t>(str1[2]) << 16) | //
A
(static_cast<uint64_t>(str1[3]) << 8) | //
R
(static_cast<uint64_t>(str1[4])); //
T

You want to torture and abuse the preprocessor, always a bad idea, to
make the second case, above, work like the first case, because you
have just too many literal strings to code by hand, poor you.

Well are you a programmer or just a whiner?

Write a program that reads a text file consisting of a single word of
five characters or less per line, and writes another text file with a
name like "my_constants.h".

How hard can it possible be to write code that reads "START" and
writes output text identical to the first quoted portion above?

Writing a small utility program is almost always a better choice than
torturing the preprocessor.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
J

James Kanze

Jack said:
On 29 Mar 2007 07:06:38 -0700, (e-mail address removed) wrote in
comp.lang.c++:

[...]
Writing a small utility program is almost always a better choice than
torturing the preprocessor.

Or using unreadable templates:). (A solution using template
meta-programming is justifiable when you need information only
available within the compiler, e.g. concerning types.)
 

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

No members online now.

Forum statistics

Threads
473,955
Messages
2,570,117
Members
46,705
Latest member
v_darius

Latest Threads

Top