【发布时间】:2021-05-31 16:50:32
【问题描述】:
有时在我的 C++ 项目中使用纯 C 库,我看到奇怪的(在我看来)函数声明。
例如:libldap 的 ldap_search_ext():https://linux.die.net/man/3/ldap_search_ext_s
int ldap_search_ext(
LDAP *ld,
char *base,
int scope,
char *filter,
char *attrs[], // this one!
int attrsonly,
LDAPControl **serverctrls,
LDAPControl **clientctrls,
struct timeval *timeout,
int sizelimit,
int *msgidp );
为什么 attrs[] 不能是 const char *?
这样的声明不想改变指针的内容而产生很多问题:
// pure C
void func(char * data[])
{
...
}
func({"blabla"}); // won't work (corrected: yes, this is wrong syntax, but it's true for structs of pointers)
const char *d[] = {"blabla", "blablu"};
func(d); // won't work
// C++
const std::string str("blabla");
char * data[] = { str.data() }; // even non-const won't work (because data() returns const*)
/// etc...
有什么理由不将此类参数声明为 const 吗?
【问题讨论】:
-
添加了
C++(在同一问题中同时使用C和C++标签的罕见情况。) -
OpenLDAP 是一个非常古老的、成熟的库。它是在
const-正确性不是事实上的要求的日子里写的。在这种情况下,它应该是一个const指针。 -
char *attrs[]与char **attrs本质上是一样的,而const char**的行为并不像您直观预期的那样,因此它可能与此有关。 -
Fwiw,
const d = {"blabla", "blablu"};无论如何都不会工作(是的,我禁用了隐式整数)。无论如何,在远程现代代码中,当指向的数据被认为是不可变的时,有 zero 理由不正确地对 any 类型的指针进行常量化。 -
顺便说一句,
func({"blabla"});不是纯 C,因为你需要一个复合文字。