Search code examples
chashcompilationtracefnv

How to compile and run FNV Hash


I am looking into open source hash functions to observe how the source code and hashing algorithm handles hash collisions. I am currently interested in low bit hash function and I found out about FNV through this other post

However, does anyone know how I can actually test this specific source code? I have tried compiling some of the C files but I keep getting errors from gcc:

hb2@hb1:~/Desktop/fnv$ gcc test_fnv.c
test_fnv.c: In function ‘unknown_hash_type’:
test_fnv.c:2183:5: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
test_fnv.c: In function ‘print_fnv32’:
test_fnv.c:2200:2: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘Fnv32_t’ [-Wformat]
test_fnv.c:2202:2: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘Fnv32_t’ [-Wformat]
test_fnv.c: In function ‘print_fnv64’:
test_fnv.c:2221:2: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘Fnv64_t’ [-Wformat]
test_fnv.c:2223:2: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘Fnv64_t’ [-Wformat]
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status
hb2@hb1:~/Desktop/fnv$

Any ideas on which files I have to specifically compile to run and test the program?

Thanks for your help in advance

FNV: info, download

After running make check, I get the following:

hb2@hb1:~/Desktop/fnv$ make check
forming longlong.h
longlong.h formed
cc -O3 -g3 fnv32.c -c
fnv32.c: In function ‘test_fnv32’:
fnv32.c:156:11: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 3 has type ‘Fnv32_t’ [-Wformat]
fnv32.c:169:8: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 4 has type ‘Fnv32_t’ [-Wformat]
fnv32.c:169:8: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 5 has type ‘Fnv32_t’ [-Wformat]
fnv32.c:183:8: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 4 has type ‘Fnv32_t’ [-Wformat]
fnv32.c:183:8: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 5 has type ‘Fnv32_t’ [-Wformat]
fnv32.c:197:8: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 4 has type ‘Fnv32_t’ [-Wformat]
fnv32.c:197:8: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 5 has type ‘Fnv32_t’ [-Wformat]
cc -O3 -g3 hash_32.c -c
cc -O3 -g3 hash_64.c -c
cc -O3 -g3 hash_32a.c -c
cc -O3 -g3 hash_64a.c -c
cc -O3 -g3 test_fnv.c -c
test_fnv.c: In function ‘unknown_hash_type’:
test_fnv.c:2183:5: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
test_fnv.c: In function ‘print_fnv32’:
test_fnv.c:2200:2: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘Fnv32_t’ [-Wformat]
test_fnv.c:2202:2: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘Fnv32_t’ [-Wformat]
test_fnv.c: In function ‘print_fnv64’:
test_fnv.c:2221:2: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘Fnv64_t’ [-Wformat]
test_fnv.c:2223:2: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘Fnv64_t’ [-Wformat]
rm -f libfnv.a
ar rv libfnv.a hash_32.o hash_64.o hash_32a.o hash_64a.o test_fnv.o
ar: creating libfnv.a
a - hash_32.o
a - hash_64.o
a - hash_32a.o
a - hash_64a.o
a - test_fnv.o
: libfnv.a
cc fnv32.o libfnv.a -o fnv032
cc -O3 -g3 fnv64.c -c
fnv64.c: In function ‘test_fnv64’:
fnv64.c:160:10: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 3 has type ‘Fnv64_t’ [-Wformat]
fnv64.c:175:8: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 4 has type ‘Fnv64_t’ [-Wformat]
fnv64.c:175:8: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 5 has type ‘Fnv64_t’ [-Wformat]
fnv64.c:190:8: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 4 has type ‘Fnv64_t’ [-Wformat]
fnv64.c:190:8: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 5 has type ‘Fnv64_t’ [-Wformat]
fnv64.c:205:8: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 4 has type ‘Fnv64_t’ [-Wformat]
fnv64.c:205:8: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 5 has type ‘Fnv64_t’ [-Wformat]
cc fnv64.o libfnv.a -o fnv064
rm -f fnv132
cp -f fnv032 fnv132
rm -f fnv164
cp -f fnv064 fnv164
rm -f fnv1a32
cp -f fnv032 fnv1a32
rm -f fnv1a64
cp -f fnv064 fnv1a64
FNV-0 32 bit tests: passed
FNV-1 32 bit tests: passed
FNV-1a 32 bit tests: passed
FNV-0 64 bit tests: passed
FNV-1 64 bit tests: passed
FNV-1a 64 bit tests: passed
hb2@hb1:~/Desktop/fnv$ 

Maybe this is what I am supposed to get, I will read the FNV more thoroughly to see how to actually run tests, but I didnt see that the first time


Solution

  • When I download FNV 5.0.3 and build it on a Mac, I get a number of compiler warnings about mismatches between the conversion specifications in the format strings and the argument actually passed. However, when I run make check, the code reports that the test vectors all pass. (It uses echo -n but the echo I've got doesn't recognize -n as an option, so the output looks a little odd.)

    Example build output:

    $ make
    forming longlong.h
    longlong.h formed
    cc -O3 -g3 hash_32.c -c
    cc -O3 -g3 hash_64.c -c
    cc -O3 -g3 hash_32a.c -c
    cc -O3 -g3 hash_64a.c -c
    cc -O3 -g3 test_fnv.c -c
    test_fnv.c:2183:5: warning: implicitly declaring library function 'exit' with type 'void (int)
          __attribute__((noreturn))'
        exit(code);
        ^
    test_fnv.c:2183:5: note: please include the header <stdlib.h> or explicitly provide a declaration
          for 'exit'
    test_fnv.c:2200:25: warning: format specifies type 'unsigned long' but the argument has type
          'unsigned int' [-Wformat]
            printf("0x%08lx %s\n", hval & mask, arg);
                      ~~~~~        ^~~~~~~~~~~
                      %08x
    test_fnv.c:2202:22: warning: format specifies type 'unsigned long' but the argument has type
          'unsigned int' [-Wformat]
            printf("0x%08lx\n", hval & mask);
                      ~~~~~     ^~~~~~~~~~~
                      %08x
    3 warnings generated.
    rm -f libfnv.a
    ar rv libfnv.a hash_32.o hash_64.o hash_32a.o hash_64a.o test_fnv.o
    ar: creating archive libfnv.a
    a - hash_32.o
    a - hash_64.o
    a - hash_32a.o
    a - hash_64a.o
    a - test_fnv.o
    : libfnv.a
    cc -O3 -g3 fnv32.c -c
    fnv32.c:156:21: warning: format specifies type 'unsigned long' but the argument has type
          'unsigned int' [-Wformat]
                        tstnum-1, hval & mask);
                                  ^~~~~~~~~~~
    fnv32.c:168:17: warning: format specifies type 'unsigned long' but the argument has type
          'unsigned int' [-Wformat]
                                program, (hval&mask),
                                         ^~~~~~~~~~~
    fnv32.c:169:8: warning: format specifies type 'unsigned long' but the argument has type
          'unsigned int' [-Wformat]
                                (fnv0_32_vector[tstnum-1].fnv0_32 & mask));
                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    fnv32.c:182:17: warning: format specifies type 'unsigned long' but the argument has type
          'unsigned int' [-Wformat]
                                program, (hval&mask),
                                         ^~~~~~~~~~~
    fnv32.c:183:8: warning: format specifies type 'unsigned long' but the argument has type
          'unsigned int' [-Wformat]
                                (fnv1_32_vector[tstnum-1].fnv1_32 & mask));
                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    fnv32.c:196:17: warning: format specifies type 'unsigned long' but the argument has type
          'unsigned int' [-Wformat]
                                program, (hval&mask),
                                         ^~~~~~~~~~~
    fnv32.c:197:8: warning: format specifies type 'unsigned long' but the argument has type
          'unsigned int' [-Wformat]
                                (fnv1a_32_vector[tstnum-1].fnv1a_32 & mask));
                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    fnv32.c:159:14: warning: 4 enumeration values not handled in switch: 'FNV_NONE', 'FNV0_64',
          'FNV1_64'... [-Wswitch]
                switch (hash_type) {
                        ^
    8 warnings generated.
    cc fnv32.o libfnv.a -o fnv032
    cc -O3 -g3 fnv64.c -c
    fnv64.c:164:14: warning: 4 enumeration values not handled in switch: 'FNV_NONE', 'FNV0_32',
          'FNV1_32'... [-Wswitch]
                switch (hash_type) {
                        ^
    1 warning generated.
    cc fnv64.o libfnv.a -o fnv064
    rm -f fnv132
    cp -f fnv032 fnv132
    rm -f fnv164
    cp -f fnv064 fnv164
    rm -f fnv1a32
    cp -f fnv032 fnv1a32
    rm -f fnv1a64
    cp -f fnv064 fnv1a64
    $
    

    Running make check:

    $ make check
    -n FNV-0 32 bit tests: 
    passed
    -n FNV-1 32 bit tests: 
    passed
    -n FNV-1a 32 bit tests: 
    passed
    -n FNV-0 64 bit tests: 
    passed
    -n FNV-1 64 bit tests: 
    passed
    -n FNV-1a 64 bit tests: 
    passed
    $
    

    The warnings are not ideal. If I get energetic, I might work on a patch and submit that to the FNV site. It depends on how much choss I get when I run with more stringent compilation options.

    Your main problem — resolved

    However, your immediate problem is that test_fnv.c is not designed to be compiled into a program on its own; it is a part of the library.