【问题标题】:return type for strchr() non const?strchr() 非 const 的返回类型?
【发布时间】:2019-03-19 00:35:22
【问题描述】:

在 Debian 9 上,使用 GCC 8.2,libc6-dev:amd64 2.27:

strchr(和许多其他<string.h> 函数)的手册页有这个原型:

   char *strchr(const char *s, int c);

当它的来源是const char *时,它如何返回非constchar *

原型不应该是const char *strchr(const char *str, int c);吗?

【问题讨论】:

  • C++ 与strchr() 存在问题正是因为这个原因。它有两种重载,一种用于const char * 参数,返回类型为const char *,另一种为char * 参数和char * 返回类型。这是 C 和 C++ 之间的众多区别之一。
  • 不要忘记 strchr() 早于标准 C。它不会修改其输入字符串,因此 const char * 适合该参数。但是标准之前没有const,所以char *是原始的返回类型。使用标准 C,这会变得有点不舒服。

标签: c pointers constants glibc


【解决方案1】:

原型不应该是 const char *strchr(const char *str, int c);

没有,因为向后兼容和更广泛的适用性。

在 C 的早期,const 并不存在,而 strchr() 很有效

char *strchr(char *str, int c);

添加const 后,将参数从char * 更改为const char * 并没有破坏现有代码,但很好地允许新代码将char *const char * 传递给strchr()。签名中的const也表明strchr(const char *str, ...)没有改变str指向的数据。

strchr() 返回const char * 会破坏现有代码。此外,当使用char * 调用strchr() 时,返回char * 就可以了。通过函数重载,就像在 C++ 中一样,这两个函数都存在。

char *strchr(char *str, int c);
const char *strchr(const char *str, int c);

同样的问题适用于许多其他函数:strto...(), bsearch(), memchr(), strpbrk(), strrchr(), strstr(), ...


这是对新代码的考虑,您是否应该开发一个返回从提供的指针派生的指针的函数:是否返回 const,或者形成 2 个函数?

const_or_not char *foo(const char *s)

【讨论】:

  • 为什么用两个答案代替一个?
  • @machine_1 SO 接口有时会复制一些东西。已删除一个答案。
  • 哦,好的。我以为发生了一些奇怪的事情:)
  • 在新代码中,您可以使用_Generic 使返回类型与参数匹配
  • 您的 const_or_not 问题很好。昨天我不得不回答这个问题,因为这整个事情都是从我开发一个strnchr() 和一个strnchrnul() 开始的,我需要实现一个strlfgrep()(一个类似fgrep 的函数来处理char *)。我得出的结论是,由于您(调用者)已经拥有非常量指针,因此您不需要返回的指针是非常量的。事实上,它的典型用法(至少我)是做指针减法并获得发现的位置,所以使用const 你就可以了。事实上,如果您使用字符串文字作为输入,则返回非常量会很危险。
【解决方案2】:

在这种情况下,const 只是表示strchr 不会更改您身上的字符串。由调用者决定是否可以修改字符串。

例如

void myFn(const char* param)
{
    char* p = strchr(param, 'A');
    /* I know there should be a NULL check too ;-) */
    *p = 'Z';
}

这是非法的,但如果参数不是const 就可以了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    • 2011-11-07
    相关资源
    最近更新 更多