为什么有些库使用非常数char*作为函数参数

  • 本文关键字:char 参数 函数 非常 c++ c libs
  • 更新时间 :
  • 英文 :


有时在我的C++项目中使用pure-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标准中从未修复的历史缺陷。

当将const添加到C中时,添加了隐式(安全(转换简单指针的能力——您可以将T *隐式转换为const T *。但是,更复杂的指针类型的(安全(转换被遗漏了——您无法将T * const *转换为const T * const *。因此,当库采用这样的双指针时,如果它是只读的,它就没有任何"好"的方法使其成为const。将其设为const char **const char * const *会破坏某些用途(需要混乱的显式强制转换(。

请注意,允许T **const T **的隐式转换是不安全的——这样的指针可以用来修改T *,使其指向不带强制转换的const T *

一个可能的原因是C中的字符串常量(与C++不同(不是const

因此,在许多本应存在的图书馆中,历史上缺乏常量正确性。如果字符串常量是const,程序员就会被迫对其进行解释

当处理这样的库时,您知道这些库不会修改参数,您必须应用const_cast使其适合。

char *d[] = {const_cast<char *>("blabla"), const_cast<char *>("blablu")};
func(d);
const std::string str("blabla");
char * data[] = { const_cast<char *>(str.data()) };
func(data);

最新更新