The following code is more efficient:
unsigned char[word_size] = ...;
int64_t num = 0;
for ( int i = 0 ; i < sizeof(a) ; i++ )
num = (num << 8) | a[i];
This assumes big endian (highest order byte first) ordering of the bytes in the array. For little endian (as you appear to use) just process it top-down:
for ( int i = sizeof(a) ; --i >= 0 ; )
Note: whether char is signed or unsigned is implementation-dependent, so nail it down to be unsigned, otherwise the logical-or will not work. Better use uint8_t; that is defined to be 8 bits, while char is not.
Note: You should use all-uppercase for constants: WORD_SIZE instead of word_size. That is a commonly accepted standard (quite the only about case for identifiers in C).
<<works fine withlong. In this case,numis always 0, and so you're clearingato all 0s.longis not necessarily 64 bits. If you want to make sure, useint64_tfromstdint.h. That is the proposed way. Also, make sure the array has the proper byte-order.