GCC抱怨同一文件中缺少对函数的引用

GCC抱怨同一文件中缺少对函数的引用,c,gcc,compiler-errors,undefined-reference,C,Gcc,Compiler Errors,Undefined Reference,沿着makefile运行,我得到以下结果: 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/mo

沿着makefile运行,我得到以下结果:

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'
并且,
3.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;

}
inline uint64\u t rotl64(uint64\u t x,int8\u t r)
{
返回(x>(64-r));
}
//-----------------------------------------------------------------------------
//终结混合-强制哈希块的所有位发生雪崩
内嵌式uint64_t fmix(uint64_t k)
{
k^=k>>33;
k*=0xff51afd7ed558ccd;
k^=k>>33;
k*=0xc4ceb9fe1a85ec53;
k^=k>>33;
返回k;
}
//-----------------------------------------------------------------------------
void-hash3_x64_128(常数void*键,常数int len,
const uint32_t seed,void*out)
{
const uint8_t*数据=(const uint8_t*)键;
常数int nblocks=len/16;
uint64_t h1=种子;
uint64_t h2=种子;
常数uint64_t c1=0x87c37b91114253d5;
常数uint64_t c2=0x4cf5ad432745937f;
//----------
//身体
常数uint64_t*块=(常数uint64_t*)(数据);
对于(int i=0;i案例15:k2^=((uint64_t)tail[14])出于某种原因,将定义从

inline type name(parameters)

解决了问题。不确定这是否是编译器错误,我必须阅读C标准

编辑:gcc v4.6.3,GNU ld v2.22


启用优化也可以解决错误(不添加static关键字),因此我不完全确定发生了什么。

出于某种原因,将定义从

inline type name(parameters)

解决了问题。不确定这是否是编译器错误,我必须阅读C标准

编辑:gcc v4.6.3,GNU ld v2.22


启用优化也会解决错误(不添加static关键字),所以我不完全确定发生了什么。

如果您以C99编译,那么编译器不必使用
内联
函数定义,但GCC会在优化时使用。不优化时,它假定程序中某处有正常的
外部
定义,这就是它试图链接的

通过将其定义为
extern inline
可以使其成为
extern
定义,因此在未优化时,可以通过调用相同或不同的翻译单元来使用它

通过定义它
静态内联
可以将其定义为
静态
定义,因此在未优化时,它将仅通过同一翻译单元中的调用使用。该
内联
定义不能用于解析其他翻译单元中的调用


有关更多详细信息,请参阅。

如果您是以C99进行编译,则编译器不必使用
内联
函数定义,但在优化时GCC会使用。如果不优化,它会假定程序中某处存在正常的
外部
定义,而这正是它试图链接到的

通过将其定义为
extern inline
可以使其成为
extern
定义,因此在未优化时,可以通过调用相同或不同的翻译单元来使用它

通过定义它
静态内联
可以将其定义为
静态
定义,因此在未优化时,它将仅通过同一翻译单元中的调用使用。该
内联
定义不能用于解析其他翻译单元中的调用


有关更多详细信息,请参阅。

您可以添加对fmix和rot164的实际调用吗?您是否尝试不使用
内联
?实际上,使用
cc
命令(减去client.o和libstorage.a)这对我来说编译很好。您使用的编译器/版本是什么?gcc 4.6.3,gnu ld 2.22如果我错了,请纠正我,但第59行'uint64_t k1=0;`不包含对rotl64的引用。请向我们提供一个没有过早优化(如内联)的测试用例,并且包含与测试用例实际相关的错误。您能将实际调用添加到fmix和rot164吗?您尝试过吗没有
inline
?实际上,使用
cc
命令(减去client.o和libstorage.a),我可以很好地编译它。您使用的编译器/版本是什么?gcc 4.6.3,gnu ld 2.22如果我错了,请纠正我,但第59行'uint64_t k1=0;`不包含对rotl64的引用。请向我们提供一个没有过早优化(如内联)的测试用例,并且包含与测试用例实际相关的错误。