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

时间:2011-08-10 18:48:02

标签: 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);
}

给出以下错误:

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]

4 个答案:

答案 0 :(得分:17)

这样的转化可让您将const char*放入char*的数组中,这将是不安全的。在print你可以做到:

thing[0] = "abc";

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

答案 1 :(得分:6)

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


问题是,如果pchar*指针,那么它可以用于修改它所指向的任何内容。

如果您可以获得指向ppp类型为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.

<小时/> 作为无法编译的代码的实用解决方案,...

#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!
}

只是做...

#include <iostream>

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

int main( int argc, char** argv )
{
    print( argv );    // OK. :-)
}

干杯&amp;第h。,

答案 2 :(得分:3)

注意,虽然

void dosmth(const char** thing);

int main(int argc, char** argv) {
  dosmth(argv);

是禁止的,你可以而且应该这样做

void dosmth(const char* const* thing);

int main(int argc, char** argv) {
  dosmth(argv);

无论如何,这可能是你想要的。这里的要点是thing现在指的是const char*数组,它本身是不可变的,引用的值char本身是不可变的。 因此,对于“查看它,但不要更改它”方案,const char* const*是要使用的类型。

注意:我使用了更常见的(但在我看来较差)标准,试图尽可能地留下const修饰符。就个人而言,我建议写char const* const*而不是const char* const*,因为它更加简洁。

答案 3 :(得分:2)

因为它可能允许我们修改常量值。请阅读此处以了解原因:http://c-faq.com/ansi/constmismatch.html