当前位置:  开发笔记 > 编程语言 > 正文

为什么我不能在C中将'char**'转换为'const char*const*'?

如何解决《为什么我不能在C中将'char**'转换为'constchar*const*'?》经验,为你挑选了3个好方法。

以下代码片段(正确)在C中发出警告,在C++中发出错误(分别使用gcc和g ++,使用版本3.4.5和4.2.1进行测试; MSVC似乎并不关心):

char **a;
const char** b = a;

我能理解并接受这个.
这个问题的C++解决方案是将b更改为const char*const*,它不允许重新分配指针并阻止你绕过const-correctness(C++ FAQ).

char **a;
const char* const* b = a;

但是,在纯C中,更正后的版本(使用const char*const*)仍会发出警告,我不明白为什么.有没有办法绕过这个而不使用演员?

澄清:
1)为什么这会在C中产生警告?它应该完全是const安全的,并且C++编译器似乎认识到它.
2)在说(并让编译器强制执行)我不会修改它指向的字符时,接受这个char**作为参数的正确方法是什么?例如,如果我想写一个函数:

void f(const char* const* in) {
  // Only reads the data from in, does not write to it
}

我想在char**上调用它,参数的正确类型是什么?

编辑:感谢那些做出回应的人,特别是那些提出问题和/或跟进我的回复的人.

我已经接受了这样一个答案,即如果没有演员阵容,我想做的事情是无法完成的,无论是否应该这样做.



1> Kevin..:

几年前我遇到了同样的问题,这让我感到厌烦.

C中的规则更简单说明(即它们不会列出转换char**为的异常const char*const*).结果,这是不允许的.使用C++标准,它们包含更多规则以允许这样的情况.

最后,它只是C标准中的一个问题.我希望下一个标准(或技术报告)能够解决这个问题.


@HappyDude:在阅读C标准之后,在第一个'const'之后所有的赌注都显示为关闭,导致编译器相信存在const正确性问题.凯文有最正确的阅读.

2> Aaron..:

>但是,在纯C中,这仍然会发出警告,我不明白为什么

您已经确定了问题 - 此代码不是常量."Const correct"意味着除了删除const的const_cast和C样式转换之外,你永远不能通过这些const指针或引用来修改const对象.

const-correctness-const的值在很大程度上是为了检测程序员错误.如果你将某些东西声明为const,那么你就是说你不认为它应该被修改 - 或者至少那些只能访问const版本的人不应该修改它.考虑:

void foo(const int*);

如声明,foo没有权限修改其参数指向的整数.

如果您不确定为什么您发布的代码不是const-correct,请考虑以下代码,与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类型只能以特定的方式转换为const类型,以防止在没有显式强制转换的情况下对数据类型的任何规避'const'.

最初声明为const的对象特别特殊 - 编译器可以假设它们永远不会改变.但是,如果'b'可以在没有强制转换的情况下赋值为'a',那么您可能会无意中尝试修改const变量.这不仅会破坏您要求编译器进行的检查,还会禁止您更改该变量值 - 它还会允许您中断编译器优化!

在一些编译器上,这将打印'42',在某些'43',以及其他编程器,程序将崩溃.

编辑补充:

HappyDude:你的评论是现货.无论是C语言还是你正在使用的C语言编译器,对于const char*const*的根本不同于C++语言对待它.也许只考虑为此源代码行静默编译器警告.

编辑删除:删除拼写错误


你所说的是正确的,但它没有解决这个问题.正如我所说,我理解为什么从char**转换为const char**是不正确的.我不明白为什么从char**转换为const char*const*是不正确的.我已经更新了我的问题以澄清.
有趣的是,这种反应不断得到投票.我想很多人都没有读过问题的前几行,我将会记住未来的事情.虽然这是一篇相当模糊的文章,但我希望它是相关的:P.
@Aaron:你的帖子与这个话题并不特别相关,但是写得很好.

3> Fabio Cecone..:

要被认为是兼容的,源指针应该是紧邻前向间接级别的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++除外).

推荐阅读
无名有名我无名_593
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有