Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hash function to switch on a string

Tags:

c++

hash

I am trying to get to work a switch on a string in C++, with the help of a hash. It became personal between me and this code, so I don't wanna give up and use an enum, even though I finally have only like 8 strings to put in switch cases.

Combining what I saw on other topics, I wrote this very simple and not so reliable function, but that is enough for what I want to do, as it's not professional.

My function :

constexpr long hashstr (const string &str, int h=0)
{
    return !str[h] ? 55 : ( hashstr(str, h+1) *33) + (unsigned char)str[h];
}

I then call it in this very simple main function (for now), but it won't compile, telling me that the case is wrong (not a constant). I don't understand this issue, as for me the string taken in arg is a constant, plus the function returns a constant expression.

My main :

int main (void) {

    string teststr;
    cout << "test string :::>  ";
    cin >> teststr;
    int tt = hashstr(teststr);
    cout << "res -->  " << tt << endl;

    switch ( hashstr(teststr) )
    {
    case hashstr("rosathefloridaturtle") :
        cout << "ROSA OK" << endl;
        break;

    default:
        cout << "ERROR" << endl;
        break;
    }

    return EXIT_SUCCESS;
}

Hoping that some of you can tell me what I'm not doing right...

like image 730
sinatrablue Avatar asked Jun 27 '26 04:06

sinatrablue


1 Answers

Unless you are using c++20 std::string is not constexpr so can't be used in hashstr.

The value returned is larger than is representable in long, as signed arithmetic overflow is undefined behaviour your code can't be used in constexpr.

Fixing these two issues gives the working code:

constexpr unsigned long hashstr (const std::string_view &str, int h=0)
{
    return !str[h] ? 55 : ( hashstr(str, h+1) *33) + (unsigned char)(str[h]);
}

Note that if you look at the compiler output it probably tells you why your expression isn't constexpr, e.g. clang prints:

error: case value is not a constant expression
    case hashstr("rosathefloridaturtle") :
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:22:18: note: non-literal type 'const std::string' (aka 'const basic_string<char>') cannot be used in a constant expression
    case hashstr("rosathefloridaturtle") :

Changing to std::string_view prints:

error: case value is not a constant expression
    case hashstr("rosathefloridaturtle") :
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:9:47: note: value 97009635813568987014 is outside the range of representable values of type 'long'
    return !str[h] ? 55 : ( hashstr(str, h+1) *33) + (unsigned char)str[h];
                                              ^
<source>:9:29: note: in call to 'hashstr("rosathefloridaturtle", 8)'
    return !str[h] ? 55 : ( hashstr(str, h+1) *33) + (unsigned char)str[h];
like image 128
Alan Birtles Avatar answered Jun 28 '26 18:06

Alan Birtles



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!