2

マクロを使用して、コンパイル時に定数 C 文字列のハッシュを計算しようとしました。それは私のコード例です:

#include <stddef.h>
#include <stdint.h>

typedef uint32_t hash_t;

#define hash_cstr(s) ({           \
      typeof(sizeof(s)) i = 0;    \
      hash_t h = 5381;            \
      for (; i < sizeof(s) - 1; ) \
        h = h * 33 + s[i++];      \
      h;                          \
    })

/* tests */
#include <stdio.h>

int main() {
#define test(s) printf("The djb2 hash of " #s " is a %u\n", hash_cstr(#s))

  test(POST);
  test(/path/to/file);
  test(Content-Length);
}

ここで、GCCを実行してリストを表示します。

arm-none-eabi-gcc-4.8 -S -O2 -funroll-loops -o hash_test.S hash_test.c

結果は予想どおりです。すべての文字列が削除され、そのハッシュに置き換えられました。しかし、通常は-Osを使用して組み込みアプリのコードをコンパイルします。やろうとすると、4文字未満の文字列のハッシュしかありません。また、パラメーターを設定してGCC 4.9max-unroll-timesを使用しようとしました:

arm-none-eabi-gcc-4.9 -S -Os -funroll-loops \
  --param max-unroll-times=128 -o hash_test.S hash_test.c

その動作の理由と、この 4 文字の制限を拡張する方法がわかりません。

4

3 に答える 3

0

C++ が許可されている場合は、次のようなテンプレート関数を使用できます。

template<int I>
  hash_t hash_rec(const char* str, hash_t h) {
  if( I > 0 ) {
    return hash_rec<I-1>(str, h * 33 + str[I-1]);
  } else {
    return h;
  }
}

#define hash(str) hash_rec<sizeof(str)>(str, 5381)

h = hash(str);
于 2015-12-17T12:20:52.663 に答える