简体   繁体   English

size_t预处理器值的大小

[英]size of size_t preprocessor value

I am creating an implementation of a hash table in C for educational purposes. 我正在C中创建一个哈希表的实现,用于教育目的。

The hash function should return a size_t hash. 散列函数应返回size_t散列。 Since the size of size_t is different in different platforms (and I want to use a hash function that hashes all the bits in a size_t), I thought of creating different hash functions for different sizes. 由于size_t的大小在不同的平台上是不同的(我想使用散列函数来散列size_t中的所有位),我想到为不同的大小创建不同的散列函数。 As the hash function will be used as a function pointer, I suspect the compiler can't inline code like this: 由于哈希函数将用作函数指针,我怀疑编译器不能像这样内联代码:

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;

And two levels of indirection will be used each time the hash function will be called. 每次调用哈希函数时都会使用两个间接级别。

That's why I thought of doing something like this: size_t (*hashFunc)(void* key, size_t size) = hash##sizeof(size_t); 这就是为什么我想做这样的事情: size_t (*hashFunc)(void* key, size_t size) = hash##sizeof(size_t); instead. 代替。 Only one level of indirection will be used. 只使用一个间接级别。 The problem is that the sizeof operator isn't available during the prepossessing phase. 问题是在prepossessing阶段期间sizeof运算符不可用。

So what would be a good way to define a preprocessor value which will expand to the correct size of size_t in each platform? 那么,定义一个预处理器值的好方法是什么,它将在每个平台中扩展到size_t的正确大小? I guess I could check against predefined macros, but I wonder if there's a better way. 我想我可以检查预定义的宏,但我想知道是否有更好的方法。

sizeof is a C-operator. sizeof是一个C运算符。 ## is a preprocessor operator. ##是一个预处理器操作符。 The latter does not know anything about the former. 后者对前者一无所知。

So you might be better of using a macro referring to the system's bit-width used for addressing, like for example testing like so: 因此,您最好使用一个宏来引用系统用于寻址的位宽,例如像这样的测试:

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

Use a 64-bit detecting macro like defined for many compilers, eg GCC uses __x86_64 使用为许多编译器定义的64位检测宏,例如GCC使用__x86_64

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

You could do this: 你可以这样做:

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

There's also nothing wrong with eznme's approach -- write a single function that behaves differently according to the size of size_t . eznme的方法也没有错 - 根据size_t的大小编写一个行为不同的函数。 Provided that you don't need the hash4 function for other purposes on 64bit implementations, of course. 当然,如果您在64位实现上不需要hash4函数用于其他目的。

Regarding the title of the question -- if you absolutely need to know about size_t at preprocessor time, then use the SIZE_MAX macro from stdint.h . 关于问题的标题 - 如果您在预处理器时间绝对需要了解size_t ,那么请使用stdint.hSIZE_MAX宏。

So what would be a good way to define a preprocessor value which will expand to the correct size of size_t in each platform? 那么,定义一个预处理器值的好方法是什么,它将在每个平台中扩展到size_t的正确大小?

According to the Glibc manual | 根据Glibc手册| Width of an Integer Type : 整数类型的宽度

TS 18661-1:2014 defines macros for the width of integer types (the number of value and sign bits). TS 18661-1:2014定义了整数类型宽度的宏(值和符号位的数量)。 One benefit of these macros is they can be used in #if preprocessor directives, whereas sizeof cannot. 这些宏的一个好处是它们可以在#if预处理器指令中使用,而sizeof则不能。 The following macros are defined in limits.h. limit.h中定义了以下宏。

 CHAR_WIDTH SCHAR_WIDTH UCHAR_WIDTH SHRT_WIDTH USHRT_WIDTH INT_WIDTH UINT_WIDTH LONG_WIDTH ULONG_WIDTH LLONG_WIDTH ULLONG_WIDTH 

These are the widths of the types char, signed char, unsigned char, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int and unsigned long long int, respectively. 这些是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的宽度。

Further such macros are defined in stdint.h. 在stdint.h中定义了更多这样的宏。 Apart from those for types specified by width (see Integers), the following are defined: 除了由width指定的类型(参见整数)之外,还定义了以下内容:

 INTPTR_WIDTH UINTPTR_WIDTH PTRDIFF_WIDTH SIG_ATOMIC_WIDTH SIZE_WIDTH WCHAR_WIDTH WINT_WIDTH 

These are the widths of the types intptr_t, uintptr_t, ptrdiff_t, sig_atomic_t, size_t, wchar_t and wint_t, respectively. 这些是intptr_t,uintptr_t,ptrdiff_t,sig_atomic_t,size_t,wchar_t和wint_t类型的宽度。

According to the manual SIZE_WIDTH is what you are looking for. 根据手册SIZE_WIDTH是你要找的。

I'm not sure of the availability with compilers like MSVC, XLC and SunCC; 我不确定MSVC,XLC和SunCC等编译器的可用性; or platforms like AIX, OX X, Solaris or Windows. 或AIX,OX X,Solaris或Windows等平台。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM