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

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

以下代码:

 #include  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] 

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

 thing[0] = "abc"; 

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

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


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

如果你可以获得指向p的指针pp ,但是使用char const**类型的pp ,那么你可以使用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  void print(const char** thing) { std::cout << thing[0] << std::endl; } int main(int argc, char** argv) { print(argv); // Dang, doesn't compile! } 

做就是了 …

 #include  void print( char const* const* thing ) { std::cout << thing[0] << std::endl; } int main( int argc, char** argv ) { print( argv ); // OK. :-) } 

干杯&hth。,

请注意,虽然

 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); 

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

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

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