2013-02-17 45 views
2

沿makefile的運行缺少函數的引用,我得到這個:GCC抱怨說在同一個文件

cc client.o MurmurHash3.o libstorage.a -Wall -lreadline -pthread -o client 
MurmurHash3.o: In function `MurmurHash3_x64_128': 
/home/evantandersen/mount/src/MurmurHash3.c:59: undefined reference to `rotl64' 
/home/evantandersen/mount/src/MurmurHash3.c:106: undefined reference to `fmix' 

而且,MurmurHash3.c

inline uint64_t rotl64 (uint64_t x, int8_t r) 
{ 
    return (x << r) | (x >> (64 - r)); 
} 

//----------------------------------------------------------------------------- 
// Finalization mix - force all bits of a hash block to avalanche 

inline uint64_t fmix (uint64_t k) 
{ 
    k ^= k >> 33; 
    k *= 0xff51afd7ed558ccd; 
    k ^= k >> 33; 
    k *= 0xc4ceb9fe1a85ec53; 
    k ^= k >> 33; 

    return k; 
} 

//----------------------------------------------------------------------------- 

void MurmurHash3_x64_128 (const void * key, const int len, 
          const uint32_t seed, void * out) 
{ 

    const uint8_t * data = (const uint8_t*)key; 
    const int nblocks = len/16; 

    uint64_t h1 = seed; 
    uint64_t h2 = seed; 

    const uint64_t c1 = 0x87c37b91114253d5; 
    const uint64_t c2 = 0x4cf5ad432745937f; 

    //---------- 
    // body 

    const uint64_t * blocks = (const uint64_t *)(data); 

    for(int i = 0; i < nblocks; i++) 
    { 
    uint64_t k1 = blocks[i*2+0]; 
    uint64_t k2 = blocks[i*2+1]; 

    k1 *= c1; k1 = rotl64(k1,31); k1 *= c2; h1 ^= k1; 

    h1 = rotl64(h1,27); h1 += h2; h1 = h1*5+0x52dce729; 

    k2 *= c2; k2 = rotl64(k2,33); k2 *= c1; h2 ^= k2; 

    h2 = rotl64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5; 
    } 

    //---------- 
    // tail 

    const uint8_t * tail = (const uint8_t*)(data + nblocks*16); 

    uint64_t k1 = 0; 
    uint64_t k2 = 0; 

    switch(len & 15) 
    { 
    case 15: k2 ^= ((uint64_t)tail[14]) << 48; 
    case 14: k2 ^= ((uint64_t)tail[13]) << 40; 
    case 13: k2 ^= ((uint64_t)tail[12]) << 32; 
    case 12: k2 ^= ((uint64_t)tail[11]) << 24; 
    case 11: k2 ^= ((uint64_t)tail[10]) << 16; 
    case 10: k2 ^= ((uint64_t)tail[ 9]) << 8; 
    case 9: k2 ^= ((uint64_t)tail[ 8]) << 0; 
      k2 *= c2; k2 = rotl64(k2,33); k2 *= c1; h2 ^= k2; 

    case 8: k1 ^= ((uint64_t)tail[ 7]) << 56; 
    case 7: k1 ^= ((uint64_t)tail[ 6]) << 48; 
    case 6: k1 ^= ((uint64_t)tail[ 5]) << 40; 
    case 5: k1 ^= ((uint64_t)tail[ 4]) << 32; 
    case 4: k1 ^= ((uint64_t)tail[ 3]) << 24; 
    case 3: k1 ^= ((int64_t)tail[ 2]) << 16; 
    case 2: k1 ^= ((uint64_t)tail[ 1]) << 8; 
    case 1: k1 ^= ((uint64_t)tail[ 0]) << 0; 
      k1 *= c1; k1 = rotl64(k1,31); k1 *= c2; h1 ^= k1; 
    }; 

    //---------- 
    // finalization 

    h1 ^= len; h2 ^= len; 

    h1 += h2; 
    h2 += h1; 

    h1 = fmix(h1); 
    h2 = fmix(h2); 

    h1 += h2; 
    h2 += h1; 

    ((uint64_t*)out)[0] = h1; 
    ((uint64_t*)out)[1] = h2; 

} 

兩個rotl64fmix在定義相同的文件和功能MurmurHash3_x64_128以上。

+0

你可以添加實際的調用fmix和rot164嗎? – 808sound 2013-02-17 05:30:03

+0

編輯添加它們。 – charliehorse55 2013-02-17 05:31:17

+0

您是否嘗試不使用'inline'? – asheeshr 2013-02-17 05:34:14

回答

4

如果您編譯爲C99,那麼編譯器不必使用inline函數定義,但GCC將在優化時使用。如果不進行優化,假定程序中某處存在正常的extern定義,這就是它試圖鏈接到的地方。

通過將其定義爲extern inline,您可以將其定義爲extern定義,因此在未優化時將使用它,方法是調用相同或不同的翻譯單元。

通過將其定義爲static inline,您可以將其定義爲static定義,因此在未優化時將使用該定義,只能使用相同翻譯單元中的調用。 inline定義不能用於解析其他翻譯單元中的調用。

有關更多詳細信息,請參見http://www.greenend.org.uk/rjk/tech/inline.html

+0

正是我在找的,謝謝。 – charliehorse55 2013-02-19 01:34:29

0

出於某種原因,改變從定義

inline type name(parameters) 

inline static type name(paramaters) 

解決的問題。不知道這是否是一個編譯器錯誤,我不得不閱讀C標準。

編輯:GCC v4.6.3,GNU LD V2.22

打開優化解決錯誤,以及(不添加static關鍵字),所以我不完全知道發生了什麼事情。