首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >模size_t产生“表达式‘’的结果未定义”

模size_t产生“表达式‘’的结果未定义”
EN

Stack Overflow用户
提问于 2021-04-08 00:00:05
回答 1查看 103关注 0票数 2

在64位系统上,当使用模运算符和size_t类型时,我从clang分析器得到以下警告:

代码语言:javascript
运行
复制
htable.c:38:62: warning: The result of the ' ' expression is undefined [clang-analyzer-core.UndefinedBinaryOperatorResult]
return ht->num_buckets > 0 ? (ht->hash_fn(key, ht->seed) % ht->num_buckets)
                                                         ^

Complete trace

哈希函数的结果是无符号的,存储桶的数量也是无符号的,最终转换成无符号size_t。AFAIK结果不能为负,我检查了存储桶的数量是否为零。

哈希函数可能会溢出,但因为它用于链哈希表,所以这不会导致问题(如果我没有弄错的话)。

这是怎么回事?这是假阳性吗?

出现警告的函数:

代码语言:javascript
运行
复制
static size_t
htable_bucket_idx(htable_t* ht, void* key)
{
    if (!ht || !key) {
        printf("htable - bucket_idx: Invalid Argument!\n");
        exit(-1);
    }

    return ht->num_buckets > 0 ? (ht->hash_fn(key, ht->seed) % ht->num_buckets)
                               : ht->hash_fn(key, ht->seed);
}

散列函数是FNV散列函数的粗略简化版本:

代码语言:javascript
运行
复制
size_t
fnv_hash_ul(const void* in, unsigned int seed)
{
    size_t             h     = seed;
    const unsigned int prime = 0xFDCFB7;
unsigned long ul = *((unsigned long*) in);

    return (h ^ ul) * prime;
}

htable_t的定义(为简洁起见,省略了其他类型,可根据请求追加)

代码语言:javascript
运行
复制
typedef size_t (*htable_hash)(const void* in, unsigned int seed);

typedef struct htable
{
    htable_hash      hash_fn;
    htable_keq       keq;
    htable_cbs_t     cbs;
    htable_bucket_t* buckets;
    size_t           num_buckets;
    size_t           num_used;
    unsigned int     seed;
} htable_t;

函数的调用:

代码语言:javascript
运行
复制
static int
htable_add_to_bucket(htable_t* ht, void* key, void* value, bool rehash)
{
    if (!ht || !key) {
        printf("htable - add_to_bucket: Invalid Argument!\n");
        exit(-1);
    }
    size_t idx = htable_bucket_idx(ht, key);

    [...]

编译器信息:

代码语言:javascript
运行
复制
clang version 11.1.0
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-pc-linux-gnu/10.2.0
Candidate multilib: .;@m64

htable.c on GitHub

htable.h on GitHub

EN

回答 1

Stack Overflow用户

发布于 2021-04-08 23:49:01

实际上,这似乎是一种错误的肯定。通过将htable_rehash()从以下位置更改,我能够消除所有警告:

代码语言:javascript
运行
复制
static int htable_rehash(htable_t* ht)
{
...
    ht->num_buckets <<= 1UL;
...
}

代码语言:javascript
运行
复制
static int htable_rehash(htable_t* ht)
{
...
    ht->num_buckets *= 2;
...
}

真奇怪。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66989783

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档