从char**隐式转换为const char**

And*_*uel 17 c c++ string gcc casting

为什么我的编译器(GCC)没有隐式地转换char**const char**

以下代码:

#include <iostream>

void print(const char** thing) {
    std::cout << thing[0] << std::endl;
}

int main(int argc, char** argv) {
    print(argv);
}
Run Code Online (Sandbox Code Playgroud)

给出以下错误:

oi.cpp: In function ‘int main(int, char**)’:
oi.cpp:8:12: error: invalid conversion from ‘char**’ to ‘const char**’ [-fpermissive]
oi.cpp:3:6: error:   initializing argument 1 of ‘void print(const char**)’ [-fpermissive]
Run Code Online (Sandbox Code Playgroud)

sth*_*sth 18

这样的转换会允许你把一个const char*放入你的数组char*,这将是不安全的.在print你可以这样做:

thing[0] = "abc";
Run Code Online (Sandbox Code Playgroud)

现在argv[0]指向一个无法修改的字符串文字,同时main期望它是非const(char*).因此,对于类型安全,不允许进行此转换.


Che*_*Alf 6

@Fred Overflow 链接到FAQ是一个完整的答案.但是(对不起马歇尔)这不是最明确的解释.我不知道我的是否更清楚,但我希望如此.


问题是,如果p是一个char*指针,那么它可以用来修改它所指向的任何东西.

如果你能获得一个指针pp指向p,但pp类型的char const**,那么你可以使用pp分配给p的地址const char.

然后,您可以使用它p来修改const char.或者,你会认为你可以.但这const char甚至可以在只读内存中......

在代码中:

char const        c = 'a';
char*             p = 0;
char const**      pp = &p;               // Not allowed. :-)

*pp = &c;        // p now points to c.
*p = 'b';        // Uh oh.
Run Code Online (Sandbox Code Playgroud)


作为无法编译的代码的实用解决方案,...

#include <iostream>

void print(const char** thing) {
    std::cout << thing[0] << std::endl;
}

int main(int argc, char** argv) {
    print(argv);    // Dang, doesn't compile!
}
Run Code Online (Sandbox Code Playgroud)

做就是了 …

#include <iostream>

void print( char const* const* thing )
{
    std::cout << thing[0] << std::endl;
}

int main( int argc, char** argv )
{
    print( argv );    // OK. :-)
}
Run Code Online (Sandbox Code Playgroud)

干杯&hth.,