首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么bsearch返回一个void *?

为什么bsearch返回一个void *?
EN

Stack Overflow用户
提问于 2011-10-29 18:36:42
回答 3查看 456关注 0票数 10
代码语言:javascript
复制
void * bsearch ( const void * key,
                 const void * base,
                 size_t num,
                 size_t size,
                 int ( * comparator ) ( const void *, const void * ) );

如果我传入一个const void * basebsearch不也应该返回一个const void *结果吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-10-29 18:41:45

当您搜索某个内容时,这是一个有效的请求,即您能够在找到它之后对其进行修改。如果搜索功能不允许您这样做,那么它将受到太多的限制。当然,这样的修改可能会破坏后续的搜索,但这是另一回事。

这些参数是const,作为bsearch本身不会修改它们的承诺,这是合理的。

票数 8
EN

Stack Overflow用户

发布于 2011-10-29 20:03:16

向指向类型添加限定符是一种隐式转换,而删除限定符需要显式强制转换。

bsearch()原型的编写方式允许在不进行显式强制转换的情况下实现以下两种用法:

代码语言:javascript
复制
int needle = 0xdeadbeef;

int foo[42] = { ... };
int *p = bsearch(&needle, foo, 42, sizeof *foo, cmpi);

const int bar[42] = { ... };
const int *q = bsearch(&needle, bar, 42, sizeof *bar, cmpi);

然而,这意味着可以使用bsearch() -以及许多其他libc函数-在没有警告的情况下删除常量限定,例如,如果我们编写了

代码语言:javascript
复制
int *q = bsearch(&needle, bar, 42, sizeof *bar, cmpi);

这是完全合法的:只有当我们实际使用q来修改bar时,才会发生未定义的行为。

您还应该记住,对指针参数进行常量限定只会影响在没有强制转换的情况下接受哪些参数,但是不能保证函数不会修改指向的对象。这只是几乎所有现有代码都遵循的约定,但它并不是由语言语义强制执行的。

特别是,编译器不能在调用代码中使用此信息进行优化-编译器需要查看函数体,因为如果对象本身未声明为const,则从指针中删除const限定并修改指向的对象是合法的。

在过去,我假设额外的限制限定指针参数将强制不可变性,但仔细重新阅读第6.7.3.1节使我相信情况并非如此:限制限定指针指向的对象上的约束只有在指针实际用于访问对象时才会生效,但是调用代码不能仅从原型...

票数 3
EN

Stack Overflow用户

发布于 2011-11-13 06:33:26

我认为这是C的类型系统中最大也是最令人讨厌的缺陷。另一个例子是strchr,这是一个具有完全相同问题的函数:它返回一个指向用户传入的资源的指针。此函数需要对常量和非常量输入参数都有用。你看到的是一种妥协。

我发现这对像这样的访问者来说是最烦人的:

代码语言:javascript
复制
const struct list *list_next(const struct list *x) { return x->next; }

对于内部使用,宏是一个很好的“多态”实现。

代码语言:javascript
复制
#define LIST_NEXT(x) ((x)->next)

但是对于外部使用,您必须使用bsearch折衷或两个单独的函数list_nextlist_next_const

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

https://stackoverflow.com/questions/7938330

复制
相关文章

相似问题

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