从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