By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,918 Members | 2,179 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,918 IT Pros & Developers. It's quick & easy.

can the pre-processor convert string literals into chars?

P: n/a
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

Mar 29 '07 #1
Share this Question
Share on Google+
2 Replies


P: n/a
On 29 Mar 2007 07:06:38 -0700, st***********@gmail.com wrote in
comp.lang.c++:
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
Mar 29 '07 #2

P: n/a
Jack Klein wrote:
On 29 Mar 2007 07:06:38 -0700, st***********@gmail.com 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.)

--
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

Mar 30 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.