为什么我不能在C中将'char **'转换为'const char * const *'?
下面的代码片段(正确地)给出了C中的警告和C ++中的错误(分别使用gcc&g ++,在版本3.4.5和4.2.1中进行了测试; MSVC似乎并不在意):
char **a;
const char** b = a;
我可以理解并接受这一点。
解决此问题的C ++解决方案是将b更改为const char * const *,它禁止重新分配指针,并且阻止您规避常量正确性(C ++ FAQ)。
char **a;
const char* const* b = a;
但是,在纯C中,更正后的版本(使用const char * const *)仍然会给出警告,我不明白为什么。 有没有办法绕过这个,而不使用演员?
澄清:
1)为什么这会在C中产生警告? 它应该完全是常量安全的,而C ++编译器似乎也是这样认识的。
2)接受这个char **作为参数的正确方法是什么,同时说(并且让编译器强制执行)我不会修改它指向的字符? 例如,如果我想写一个函数:
void f(const char* const* in) {
// Only reads the data from in, does not write to it
}
我想在char **上调用它,参数的正确类型是什么?
编辑:感谢那些已经回复的人,尤其是那些回答问题和/或跟进我的回复的人。
我已经接受了这样的答案,即如果没有演员阵容,我想要做的事情不可能完成,不管它是否可能。
几年前,我也遇到了同样的问题,它让我感到无法接受。
C中的规则更简单地陈述(即,它们不会列出将char**
转换为const char*const*
异常)。 结果,这只是不被允许的。 在C ++标准中,它们包含了更多的规则来允许这样的情况。
最后,这只是C标准中的一个问题。 我希望下一个标准(或技术报告)能解决这个问题。
>然而,在纯C中,这仍然会给出警告,我不明白为什么
你已经发现了这个问题 - 这段代码不是const正确的。 “Const correct”意思是,除了const_cast和C-style强制转换删除const之外,你永远不能通过这些const指针或引用修改const对象。
常量正确性的值 - const在很大程度上是为了检测程序员错误。 如果你将某些东西声明为const,那么你就说你不认为它应该被修改 - 或者至少,那些有权访问const版本的人不应该修改它。 考虑:
void foo(const int*);
正如所声明的,foo没有修改其参数指向的整数的权限。
如果您不确定为什么您发布的代码不是常量不正确的,请考虑以下代码,与HappyDude的代码略有不同:
char *y;
char **a = &y; // a points to y
const char **b = a; // now b also points to y
// const protection has been violated, because:
const char x = 42; // x must never be modified
*b = &x; // the type of *b is const char *, so set it
// with &x which is const char* ..
// .. so y is set to &x... oops;
*y = 43; // y == &x... so attempting to modify const
// variable. oops! undefined behavior!
cout << x << endl;
非常量类型只能以特定方式转换为常量类型,以防止在没有显式强制转换的情况下规避数据类型的“常量”。
最初声明const的对象特别特别 - 编译器可以假定它们永远不会改变。 然而,如果'b'可以在没有强制转换的情况下分配'a'的值,那么你可能会不经意地尝试修改一个const变量。 这不仅会中断您要求编译器进行的检查,不允许您更改该变量值 - 它还会允许您中断编译器优化!
在某些编译器上,这将打印'42',在某些'43'等打印机上,程序将崩溃。
编辑补充:
HappyDude:您的评论是关注的。 无论是C语言还是您使用的C编译器,对待const char * const *的处理方式都与C ++语言的处理方式根本不同。 也许可以考虑只沉默这个源代码行的编译器警告。
编辑 - 删除:删除错字
为了被认为是兼容的,源指针应该是在前面的间接层次上是const的。 所以,这会给你GCC的警告:
char **a;
const char* const* b = a;
但是这不会:
const char **a;
const char* const* b = a;
或者,你可以施放它:
char **a;
const char* const* b = (const char **)a;
您将需要相同的强制转换来调用函数f(),如您所述。 据我所知,在这种情况下无法进行隐式转换(C ++除外)。
链接地址: http://www.djcxy.com/p/28353.html上一篇: Why can't I convert 'char**' to a 'const char* const*' in C?
下一篇: c++