benlaurie / objecthash

A way to cryptographically hash objects (in the JSON-ish sense) that works cross-language. And, therefore, cross-encoding.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

C code doesn't compile with gcc 4.8

AlCutter opened this issue · comments

cc -Wall -Werror -I/usr/local/include -o objecthash_test objecthash_test.c objecthash.c crypto-algorithms/sha256.c -L/usr/local/lib -ljson-c
In file included from objecthash_test.c:1:0:
objecthash.h:10:14: error: variably modified ‘hash’ at file scope
 typedef byte hash[HASH_SIZE];
              ^
objecthash_test.c: In function ‘a_to_hash’:
objecthash_test.c:8:3: error: ‘for’ loop initial declarations are only allowed in C99 mode
   for (int n = 0; n < HASH_SIZE; ++n)
   ^
objecthash_test.c:8:3: note: use option -std=c99 or -std=gnu99 to compile your code
In file included from objecthash.c:6:0:
objecthash.h:10:14: error: variably modified ‘hash’ at file scope
 typedef byte hash[HASH_SIZE];
              ^
In file included from /usr/include/json-c/linkhash.h:16:0,
                 from /usr/include/json-c/json.h:22,
                 from objecthash.c:2:
objecthash.c: In function ‘object_hash_dict’:
objecthash.c:56:40: error: variable ‘val’ set but not used [-Werror=unused-but-set-variable]
     json_object_object_foreach(d, key, val) {
                                        ^
objecthash.c:56:35: error: variable ‘key’ set but not used [-Werror=unused-but-set-variable]
     json_object_object_foreach(d, key, val) {
                                   ^
objecthash.c: In function ‘object_hash_list’:
objecthash.c:148:3: error: ‘for’ loop initial declarations are only allowed in C99 mode
   for (int n = 0; n < len; ++n) {
   ^
objecthash.c:148:3: note: use option -std=c99 or -std=gnu99 to compile your code
cc1: all warnings being treated as errors
make: *** [objecthash_test] Error 1

Adding -std=c99 should fix this. Does leave another minor problem, tho:

objecthash.c: In function 'object_hash_dict':
objecthash.c:60:40: error: variable 'val' set but not used [-Werror=unused-but-set-variable]
json_object_object_foreach(d, key, val) {

This still seems to be broken even though the command includes -std=c99.

Here's what I get when I run make c:

cc -fPIC -shared -std=c99 -Wall -Werror -o libobjecthash.so objecthash.c -lcrypto `pkg-config --libs --cflags icu-uc json-c`
In file included from objecthash.c:14:0:
objecthash.h:13:14: error: variably modified ‘hash’ at file scope
 typedef byte hash[HASH_SIZE];
              ^
In file included from /usr/include/json-c/linkhash.h:16:0,
                 from /usr/include/json-c/json.h:22,
                 from objecthash.c:2:
objecthash.c: In function ‘object_hash_dict’:
objecthash.c:62:40: error: variable ‘val’ set but not used [-Werror=unused-but-set-variable]
     json_object_object_foreach(d, key, val) {
                                        ^
objecthash.c:62:35: error: variable ‘key’ set but not used [-Werror=unused-but-set-variable]
     json_object_object_foreach(d, key, val) {
                                   ^
objecthash.c:66:3: error: implicit declaration of function ‘alloca’ [-Werror=implicit-function-declaration]
   byte *hashes = alloca(2 * len * sizeof(hash));
   ^
objecthash.c:66:18: error: initialization makes pointer from integer without a cast [-Werror]
   byte *hashes = alloca(2 * len * sizeof(hash));
                  ^
objecthash.c: In function ‘unicode_normalize_string’:
objecthash.c:259:17: error: initialization makes pointer from integer without a cast [-Werror]
     UChar *us = alloca(length * sizeof(UChar));
                 ^
objecthash.c:265:18: error: initialization makes pointer from integer without a cast [-Werror]
     UChar *usn = alloca(uslength * 10 * sizeof(UChar));
                  ^
objecthash.c:275:16: error: initialization makes pointer from integer without a cast [-Werror]
     char *n8 = alloca(n8length);
                ^
cc1: all warnings being treated as errors
make: *** [libobjecthash.so] Error 1

I think this is because of the following issues:

  • The "variably modified ‘hash’ at file scope" error is because HASH_SIZE was defined as a const variable. In C, unlike C++ const values are not true constants. They are stored in memory and can be referenced and modified indirectly (by modifying the contents in memory). This can be fixed by defining HASH_SIZE as a macro.
  • The "unused-but-set-variable" errors can be fixed by casting the unused variables to void, which silences the warning.
  • The remaining errors are because alloca is not defined because the <alloca.h> header was removed in ac23d2a. As stated in the commit message for ac23d2a, it's best to avoid using alloca because it's not portable. I think it's better to use malloc/free here instead. Not only because it's more portable but also because the values being hashed might be arbitrarily large, which can be problematic when using alloca.