Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > can the pre-processor convert string literals into chars?

Reply
Thread Tools

can the pre-processor convert string literals into chars?

 
 
steve.lorimer@gmail.com
Guest
Posts: n/a
 
      03-29-2007
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') << | // 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) << | // 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]) << | //
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]) << | //
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])
<< | \
(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

 
Reply With Quote
 
 
 
 
Jack Klein
Guest
Posts: n/a
 
      03-29-2007
On 29 Mar 2007 07:06:38 -0700, http://www.velocityreviews.com/forums/(E-Mail Removed) 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') << | // 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]) << | //
> 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
 
Reply With Quote
 
 
 
 
James Kanze
Guest
Posts: n/a
 
      03-30-2007
Jack Klein wrote:
> On 29 Mar 2007 07:06:38 -0700, (E-Mail 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.)

--
James Kanze (GABI Software) email:(E-Mail Removed)
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

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Split string (then) Convert string into Integer news ASP General 2 05-26-2010 11:58 AM
can the pre-processor convert string literals into chars? steve.lorimer@gmail.com C++ 10 04-02-2007 03:06 PM
Where can I find more about string literals? WaterWalk C Programming 7 03-20-2006 11:12 PM
Java: byte literals and short literals John Goche Java 8 01-17-2006 11:12 PM
Perl regex to remove c-comments, taking into account string literals Saeed Perl Misc 1 07-10-2004 09:12 PM



Advertisments