不允许将char**传递给接受const char**的函数

q9yhzks0  于 2023-06-28  发布在  其他
关注(0)|答案(1)|浏览(106)

我读了这个answer,但我仍然不清楚:
类似于:

#include <stddef.h>

size_t
foo(const char ** str)
{
  size_t i = 0;
  while (*str[0])
    i++;
  return i;
}

int main (int argc, char ** argv)
{
  foo(argv);
}

编译为

$ gcc main.c
main.c: In function 'main':
main.c:14:7: warning: passing argument 1 of 'foo' from incompatible pointer type [-Wincompatible-pointer-types]
   14 |   foo(argv);
      |       ^~~~
      |       |
      |       char **
main.c:4:19: note: expected 'const char **' but argument is of type 'char **'
    4 | foo(const char ** str)

我的基本问题是:为什么我不能做更多的const?我想说的是:我不会修改的字符,在这个函数。
对我来说,这似乎与另一个答案给出的情况不同,在另一个答案中,你欺骗自己的方式违反了charconst性质。

6jygbczu

6jygbczu1#

我的基本问题是:为什么我不能做更多的const
char **是指向char *的指针。将其更改为const char **不会使其成为指向char *类型的const的指针;那就是char * const *它将其更改为指向不同类型的指针。
您可以将char **更改为char * const *;将接受该类型的隐式转换。
问题是:

  • 类型char *受到保护,不会被分配const char *。给定char *p;const char *cp;,则不允许p = cp;
  • 类型const char *没有这种保护,因为将const char *分配给const char *当然是可以的。
  • 如果将char **更改为const char **,则将删除保护。
  • 给定char *pp = &p;pp指向一个受保护的对象。
  • 如果pp被传递给void foo(const char **cpp),则类型const char **cpp表示*cpp不受保护。因此,foo可以执行*cpp = &cp;,这会将pp更改为指向const char *,这是不允许的。

对我来说,这似乎与另一个答案给出的情况不同,...
不,是一样的:

static const char *s = "Test";

void foo(const char **cpp)
{
    *cpp = s;
}

#include <stddef.h>

int main(void)
{
    char *p = NULL;
    char **pp = &p;
    foo(pp);  // Pass "char **" for "const char **", which is disallowed.

    *p = 0; //  Now p points to s, so this attempts to change a const char.
}

相关问题