【问题标题】:Why I can't pass an argument of type 'char* const *' to a function which expected 'const char* const*' as it's argument? [duplicate]为什么我不能将 'char* const *' 类型的参数传递给期望 'const char* const*' 作为参数的函数? [复制]
【发布时间】:2020-11-03 12:35:25
【问题描述】:

我正在编写一个函数,使用 fork 和 execv 来替换项目中的 system()popen()。 我发现虽然execv不会改变命令数组的内容,但是它声明它的第二个参数为char * const argv[],实际上可以改变char*的内容。因此我决定像这样声明我的函数:int execute_cmd(const char* const cmd[]) 这样指向 char 的指针都是 const 并且 const 指针指向的内容是 const(对不起,我知道这种状态令人困惑,但我试过了) 但是,当我这样称呼它时:

void execute_cmd(const char* const cmd[])
{
    for (int i = 0; cmd[i]; i++)
    {
        printf("%s ", cmd[i]);
    }
}

int main()
{
    char* const cmd[] = {"ls", "-al", 0};
    execute_cmd(cmd);
    return 0;
}

有一个编译错误说:

test.c:21: 警告:从'execute_cmd' 传递参数 1 指针类型不兼容

test.c:10:注意:预期为“const char * const*”,但参数为 输入‘char * const*’

我想知道为什么会发生这种情况,因为 IMO 带有 const 的形式参数可以将非常量变量作为实际参数,例如:

void printInt(const int);
//which can call like this
int a=10;
printInt(a);

而且我认为用非常量变量初始化 const 变量是很常见的,那么为什么这个函数有效但我的 execute_cmd() 没有呢?我错过了 const 的重要内容吗? 我搜索了“char * const * and const char* const *”和“带有非 const 实际参数的 const 形式参数”这样的东西,但没有得到非常有用的东西,如果有人能给我一个想法,我也将不胜感激这个问题的正确关键工作。 我不是以英语为母语的,所以如果有语法问题请见谅。

【问题讨论】:

  • 试试char * const cmd[] = {"ls", "-al", 0};
  • "这实际上可以改变char*的内容" --> 代码不应试图改变"ls"
  • @chux-ReinstateMonica 是的,是char * const cmd[],我写错了
  • 您将顶级const(例如const int)与指向对象(例如char const*)上的const 混淆了。相对于指针星号的位置至关重要。正确的是,您不能只将一个表示它不会修改指向对象的指针传递给一个声明自己采用可能的指针的函数。剩下的只是如何解决糟糕的const-API 或 C 本身的正确性问题。
  • @chux-ReinstateMonica 发布了最小化代码可能会导致问题。和真正的 gcc 的消息

标签: c


【解决方案1】:

我想知道为什么会发生这种情况,因为 IMO 带有 const 的形式参数可以将非常量变量作为实际参数

这更像是“带有const 的形式参数可以将非const 变量作为实际参数。”

const char* const cmd_paramter[] 就像一个“指向 const char 的 const 指针数组”。

char* const cmd_argument[] 是一个“指向 char 的 const 指针数组”。

注意数组元素的类型不同:const char *char *

更简单的代码也有同样的问题:“预期为 'char *' 但参数的类型为 'const char *'”

void foo(char *bob);
const char *alice = "Alice";

// Bad, as `foo()` needs to be able to write `*bob`, yet alice point to `const` data.
foo(alice);  

此外,cmd 数组元素的类型应为 const char * 以防止写入 字符串文字

    // char* const cmd[] = {"ls", "-al", 0};
    const char* const cmd[] = {"ls", "-al", 0};

【讨论】:

  • “更简单的代码也有同样的问题”代码示例离题了。 OP 清楚地知道不能将 const 分配给非常量;问题是关于相反的方向。我认为您答案的第二部分是迄今为止最好的建议:如果可能,请将所有内容都设为 const。
猜你喜欢
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多