2013-02-18 4 views
3

나는 교육 목적으로 C로 해시 테이블을 구현하려고합니다.크기 size_t preprocessor 값

해시 함수는 size_t 해시를 반환해야합니다. size_t의 크기가 플랫폼마다 다르므로 size_t의 모든 비트를 해쉬하는 해시 함수를 사용하고 싶습니다. 다른 크기의 해시 함수를 여러 개 만들려고했습니다. 간접

size_t hash4(void* key, size_t size); 
size_t hash8(void* key, size_t size); 

size_t hash(void* key, size_t size) 
{ 
    if (sizeof(size_t) == 4) 
    { 
     return hash4(key, size); 
    } 
    else if (sizeof(size_t) == 8) 
    { 
     return hash8(ket, size); 
    } 
} 

size_t (*hashFunc)(void* key, size_t size) = hash; 

그리고이 수준이 해시 함수가 호출 될 때마다 사용됩니다 해쉬 함수는 함수 포인터로 사용됩니다, 나는 컴파일러는이 같은하지 인라인 코드 수 있습니다 생각한다.

그런 이유로 나는 이런 식으로 생각했다 : size_t (*hashFunc)(void* key, size_t size) = hash##sizeof(size_t);. 간접 지정은 한 단계 만 사용됩니다. 문제는 prepossessing 단계에서 sizeof 연산자를 사용할 수 없다는 것입니다.

그렇다면 각 플랫폼에서 size_t의 올바른 크기로 확장되는 선처리 프로세서 값을 정의하는 좋은 방법은 무엇입니까? 사전 정의 된 매크로를 검사 할 수 있다고 생각합니다. 그러나 더 좋은 방법이 있는지 궁금합니다.

답변

1

을 당신은이 작업을 수행 할 수 있습니다 : 예를 들어과 같이 테스트 같은

그래서 당신은 주소에 사용되는 시스템의 비트 폭 참조 매크로를 사용하여 더 좋을 수도 eznme의 접근법에는 아무런 문제가 없습니다. size_t의 크기에 따라 다르게 동작하는 단일 함수를 작성하십시오. 물론, 당신이 다른 목적을 위해 hash4 함수를 64 비트 구현에서 필요로하지 않는다면.

질문 제목과 관련하여 - 사전 처리기 시간에 size_t을 절대적으로 알아야 할 경우 의 SIZE_MAX 매크로를 사용하십시오.

+0

분명히, 구조체 내부에서 상수 함수 포인터를 초기화하는 데 사용할 수 있으므로 실제로이 포인터를 선호한다고 생각합니다. –

2

같은 많은 컴파일러에 정의 된 64 비트 탐지 매크로를 사용하십시오. GCC는 __x86_64

size_t hash(void* key, size_t size) { 
    #ifdef __x86_64 
     compute 64bit hash 
    #else 
     compute 32bit hash 
    #endif 
} 
+4

만약'if (sizeof (size_t) == 8) '라고 쓰면 최적화 된 수준에서 방출 된 코드는 실제로 테스트를 수행하지 않을 것이며 컴파일러는 어떤 분기가 죽었는지 제거 할 것입니다. 하지만 컴파일 할 때 두 가지 분기가 필요합니다. –

3

sizeof는 C-연산자를 이용한다. ##은 전 처리기 연산자입니다. 후자는 전자에 대해 아무것도 모른다.

size_t (*hashFunc)(void* key, size_t size) = (sizeof(size_t) == 8) ? hash8 : hash4; 

:

#if UINTPTR_MAX == 0xffffffffffffffff 
/* it's 64bits pointers */ 
#elif UINTPTR_MAX == 0xffffffff 
/* it's 32bits pointers */ 
#endif 
+0

sizeof를 전처리 연산자로 사용할 수 없다는 것을 알고 있습니다. 어쨌든, 나는이 솔루션이 마음에 든다. 나는 eznme가 제안한 것과 함께 사용할 것이라고 생각한다. –