C++:char**到constchar**的转换

C++: char** to const char** conversion

本文关键字:转换 constchar char C++      更新时间:2023-10-16

在C++中,当可以从char*转换为const char*时,为什么不能将char**作为参数传递给接受const char**的函数,如下所示

void f1(const char** a)
{
}
void f2(const char* b)
{
}
int main(int argc, char const *argv[])
{
   char* c;
   f1(&c); // doesn't work
   f2(c); //works
   return 0;
}

编译器输出为

test.cpp:在函数"int main(int,const char**)"中:test.cpp:15:10:错误:从"char**"到"const char**"的转换无效[-fpermission]test.cpp:1:6:错误:初始化"void f1(const char**)"的参数1[-fpermission]

您需要保护指针的两个取消引用级别上的内容。使用const char**,您实际上可以修改第一个取消引用的内容。

char *tmp = "foo"; //Deprecated but it's ok for the example
void f1(const char** a)
{
  a[0] = tmp;     //this is legal
  a[0][1] = 'x';  //this is not
}

这很可能不是有意的。它应该是这样的:

char *tmp = "foo"; //Deprecated but it's ok for the example
void f1(char const* const* a)
{
  a[0] = tmp;    // this is not legal any more
  a[0][1] = 'x'; // this still upsets compiler
}

编译器不允许隐式转换为这种"部分"受保护的指针类型。正如@zmb在评论中指出的c++faq中所讨论的那样,允许这种转换可能会产生恶劣的后果。这个答案还引用了使用char示例,如果允许的话,如何违反对象的常量

然而,可以隐式地转换为"完全"受保护的指针,如第二个代码示例所示,因此下面的代码可以编译。

void f1(char const* const* a){}
void f2(const char* b){}
int main(int argc, char const *argv[])
{
   char* c;
   f1(&c); // works now too!
   f2(c);  // works
   return 0;
}

事实上,这件事有很多问题和答案。例如:

  1. 从"char**"到"const char**"的转换无效
  2. 为什么我在将"float***"转换为"constfloat**"时出错

编辑:我把第一个例子错了一点。谢谢你指出!