C语言 size_t预处理器值的大小

ie3xauqp  于 2023-04-19  发布在  其他
关注(0)|答案(5)|浏览(138)

我正在创建一个C中的哈希表的实现,用于教育目的。
哈希函数应该返回一个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);。只会使用一个间接层。问题是sizeof操作符在预处理阶段不可用。
那么,定义一个预处理器值的好方法是什么呢?它将在每个平台上扩展到size_t的正确大小?我想我可以检查预定义的宏,但我想知道是否有更好的方法。

ncecgwcz

ncecgwcz1#

sizeof是一个C操作符。##是一个预处理器操作符。后者不知道前者的任何信息。
所以你可能会更好地使用一个宏引用系统的位宽用于寻址,例如测试如下:

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

lfapxunr2#

你可以这样做:

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

eznme的方法也没什么问题--编写一个函数,根据size_t的大小表现不同。当然,前提是在64位实现中不需要hash4函数用于其他目的。
关于问题的标题--如果你绝对需要在预处理器时了解size_t,那么就使用stdint.h中的SIZE_MAX宏。

uujelgoq

uujelgoq3#

使用64位检测宏,就像为许多编译器定义的那样,例如GCC使用__x86_64

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

zd287kbt4#

那么,定义一个预处理器值的好方法是什么呢?它将在每个平台上扩展到size_t的正确大小?
根据Glibc manual | Width of an Integer Type
TS 18661-1:2014定义了整数类型宽度(值和符号位的数量)的宏。这些宏的一个好处是它们可以在#if预处理器指令中使用,而sizeof不能。以下宏在limits. h中定义。

CHAR_WIDTH
SCHAR_WIDTH
UCHAR_WIDTH
SHRT_WIDTH
USHRT_WIDTH
INT_WIDTH
UINT_WIDTH
LONG_WIDTH
ULONG_WIDTH
LLONG_WIDTH
ULLONG_WIDTH

它们分别是char、signed char、unsigned char、short int、unsigned short int、int、unsigned int、long int、unsigned long int、long long int和unsigned long long int类型的宽度。
在stdint. h中定义了更多这样的宏。除了那些由width指定的类型(参见Integers)之外,还定义了以下宏:

INTPTR_WIDTH
UINTPTR_WIDTH
PTRDIFF_WIDTH
SIG_ATOMIC_WIDTH
SIZE_WIDTH
WCHAR_WIDTH
WINT_WIDTH

这些分别是类型intptr_t、uintptr_t、ptrdiff_t、sig_atomic_t、size_t、wchar_t和wint_t的宽度。
根据手册SIZE_WIDTH是你正在寻找的。
我不确定MSVC、XLC和SunCC等编译器是否可用;或AIX、OX X、Solaris或Windows等平台。

hwamh0ep

hwamh0ep5#

#include <cstdint>
#include <limits.h>

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 SIZE_MAX == UINT32_MAX
            return hash4(key, size);
    #elif SIZE_MAX == UINT64_MAX
            return hash8(ket, size);
    #else
            static_assert(false, "Not implemented.");
    #endif
}

参考资料

相关问题