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

Passing char ** to function accepting const char ** not allowed

提问人:user129393192 提问时间:6/23/2023 更新时间:6/23/2023 访问量:77

问:

我读了这个答案,但我仍然不清楚:

像这样:

#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

在我看来,这似乎与另一个答案给出的情况不同,在另一个答案中,你试图以自己的方式违反 .constchar

c 字符串 指针 编译器错误 约束

评论

1赞 n. m. could be an AI 6/23/2023
“我想说的是:我不会修改这个功能中的角色。C 语言不允许你方便地表达这个承诺。在 C++ 中,您可以编写并且它工作得很好,但是 C 缺乏从 到 的隐式转换。const char* const* strT**const T* const*
0赞 selbie 6/23/2023
仅供参考... 是函数内部的无限循环。我不确定这是否与你的问题有关。但我想你真的是说while (*str[0]) i++;foowhile (*str[i]) i++;
0赞 chux - Reinstate Monica 6/23/2023
@user129393192,“为什么我不能做一些更常的事情”——> IIRC,C23 有一个更新来应对这个问题并允许它。
0赞 user129393192 6/23/2023
但是,埃里克在回答中提到的问题会发生什么?@chux-恢复莫妮卡
0赞 chux - Reinstate Monica 6/23/2023
@user129393192 关于C23的详细解释,最好先等它发布。

答:

0赞 Eric Postpischil 6/23/2023 #1

我的基本问题是:为什么我不能做更多的东西?const

A 是指向 的指针。将其更改为不会使它成为指向 a 类型的指针;那将是.它将其更改为指向其他类型的指针。char **char *const char **constchar *char * const *

您可以更改为 ;将接受该类型的隐式转换。char **char * const *

问题是:

  • 该类型受到保护,不会被分配 .给定 和 是不允许的。char *const char *char *p;const char *cp;p = cp;
  • 该类型没有这种保护,因为当然可以将 a 分配给 .const char *const char *const char *
  • 如果更改为 ,则将删除保护。char **const char **
  • 给定 ,指向受保护的事物。char *pp = &p;pp
  • 如果传递给 ,则类型表示不受保护。因此可以做 ,其更改指向 ,这不应该被允许。ppvoid foo(const char **cpp)const char **cpp*cppfoo*cpp = &cp;ppconst 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.
}

评论

0赞 user129393192 6/23/2023
我无法关注这个问题。具体来说,您要删除哪些保护?
0赞 Eric Postpischil 6/23/2023
@user129393192:不允许给定 和 。A 不会被分配 类型的值。char *p;const char *cp;p = cp;char *const char *
1赞 user129393192 6/23/2023
要点中有错别字吗?我仍然无法理解它。具体来说,第四个应该有吗?第三个,你如何通过分配给一个来消除保护,这似乎是额外的保护,是我困惑的要点,我认为这与第四个有关,你说指向一个受保护的东西。char ** pp = &pchar**const char**pp