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
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;
}
//--------------------------------------------------------------------------

 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      03-29-2007
* http://www.velocityreviews.com/forums/(E-Mail Removed):
> Obviously performance wise this is far better than:


Measure.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
 
 
 
steve.lorimer@gmail.com
Guest
Posts: n/a
 
      03-29-2007
On Mar 29, 3:08 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
>
> Measure.
>


Are you saying that for a dataset of n 5-character strings, it could
be faster for the CPU to execute:

if (strncmp(input, str_1, 5) == 0) return val_1;
else
if (strncmp(input, str_2, 5) == 0) return val_2;
else
...
else
if (strncmp(input, str_n, 5) == 0) return val_n;

rather than this?

uint64_t val = convert_5_char_str_to_uint64(input);
switch(val)
{
case str_1_as_uint64: return val_1;
case str_2_as_uint64: return val_2;
...
case str_n_as_uint64: return val_n;
default: return -1;
}

Thanks, Steve

 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      03-29-2007
* (E-Mail Removed):
> On Mar 29, 3:08 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
>> Measure.
>>

>
> Are you saying that for a dataset of n 5-character strings, it could
> be faster for the CPU to execute:
>
> if (strncmp(input, str_1, 5) == 0) return val_1;
> else
> if (strncmp(input, str_2, 5) == 0) return val_2;
> else
> ...
> else
> if (strncmp(input, str_n, 5) == 0) return val_n;
>
> rather than this?
>
> uint64_t val = convert_5_char_str_to_uint64(input);
> switch(val)
> {
> case str_1_as_uint64: return val_1;
> case str_2_as_uint64: return val_2;
> ...
> case str_n_as_uint64: return val_n;
> default: return -1;
> }


I'm saying you're probably doing premature optimization.

The first is probably fast enough, no need to complicate.

Anyway, use a std::map, avoid non-standard types, etc.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
steve.lorimer@gmail.com
Guest
Posts: n/a
 
      03-29-2007
On Mar 29, 3:20 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
> I'm saying you're probably doing premature optimization.
>
> The first is probably fast enough, no need to complicate.
>


Thanks Alf. Another question though. How can I measure 1st vs the 2nd,
if I can't get the 2nd to compile?

This is for a algorithmic trading system, where every micro-second
counts. Perhaps I am doing premature optimization, but I'm afraid my
knowledge of gcc and/or suncc optimizations is sparse, so I prefer to
err on the side of caution.

> Anyway, use a std::map, avoid non-standard types, etc.
>


I did use this in the end... or at least something similar: a sorted
list with a binary search. Easy-peasy.
However, for interest's sake - I'm still keen to know if there is a
way to get the pre-processor to convert string literals into chars.

Any takers?!
TIA Steve

 
Reply With Quote
 
steve.lorimer@gmail.com
Guest
Posts: n/a
 
      03-29-2007
On Mar 29, 3:20 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
>
> I'm saying you're probably doing premature optimization.
>
> The first is probably fast enough, no need to complicate.
>

Please could someone who knows about the optimizations employed these
days answer this:

Can the optimizer convert

if (strncmp(input, str_1, 5) == 0) return val_1;
else
if (strncmp(input, str_2, 5) == 0) return val_2;
else
...
else
if (strncmp(input, str_n, 5) == 0) return val_n;

into a table-based lookup, such as what happens to switch statements?

My belief is that string compares are very expensive... but maybe
that's coz I'm too old-school!

If the compiler can optimize the above string-compare block into a
table -based lookup, then I say groovy!

 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      03-29-2007
* (E-Mail Removed):
> On Mar 29, 3:20 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
>> I'm saying you're probably doing premature optimization.
>>
>> The first is probably fast enough, no need to complicate.
>>

> Please could someone who knows about the optimizations employed these
> days answer this:
>
> Can the optimizer convert
>
> if (strncmp(input, str_1, 5) == 0) return val_1;
> else
> if (strncmp(input, str_2, 5) == 0) return val_2;
> else
> ...
> else
> if (strncmp(input, str_n, 5) == 0) return val_n;
>
> into a table-based lookup, such as what happens to switch statements?


Generally not.


> My belief is that string compares are very expensive... but maybe
> that's coz I'm too old-school!


Sounds more like not-quite-out-of-school.


> If the compiler can optimize the above string-compare block into a
> table -based lookup, then I say groovy!


Yeah, that would be something.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
steve.lorimer@gmail.com
Guest
Posts: n/a
 
      03-29-2007
On Mar 29, 3:40 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
> Generally not.


Hence the reason I'm asking this question Alf! Like I said, every
micro-second counts.

> Sounds more like not-quite-out-of-school.


What are you saying here... that string compares as opposed to a table-
based lookup are or are not faster? Please stay on topic and answer
the question. If I'm incorrect in saying string compares are
expensive, I'm happy to be told so, but please correct me rather than
attempting to insult me. A reasonable explanation would be fantastic.

> Yeah, that would be something.


Again, the reson I ask the question... If you know the answers, please
reply. If not - please refrain from insults.

 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      03-29-2007
* (E-Mail Removed):
> On Mar 29, 3:40 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
>> Generally not.

>
> Hence the reason I'm asking this question Alf! Like I said, every
> micro-second counts.
>
>> Sounds more like not-quite-out-of-school.

>
> What are you saying here... that string compares as opposed to a table-
> based lookup are or are not faster? Please stay on topic and answer
> the question. If I'm incorrect in saying string compares are
> expensive, I'm happy to be told so, but please correct me rather than
> attempting to insult me. A reasonable explanation would be fantastic.
>
>> Yeah, that would be something.

>
> Again, the reson I ask the question... If you know the answers, please
> reply. If not - please refrain from insults.


See above.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
David Harmon
Guest
Posts: n/a
 
      03-29-2007
On 29 Mar 2007 07:36:01 -0700 in comp.lang.c++, (E-Mail Removed)
wrote,
>Can the optimizer convert

....
>into a table-based lookup, such as what happens to switch statements?


The compiler will never generate a straight table indexed by a uint64_t.
That would be a table how many terrabytes in size? If you could even do
it, all your hoped for performance would disappear in cache thrashing.
The compiler will at best convert your very sparse switch statement into
a chain of if-else-if like tests.

The preceeding paragraph is guesswork. Never guess about performance.
If you need to know, measure.

As Alf said, use std::map, or consider some hashed unordered_map.

 
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++ 2 03-30-2007 07:47 AM
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