【发布时间】:2016-02-10 15:55:10
【问题描述】:
我知道从 char ** 到 const char ** 的隐式转换无法完成以及为什么,并且到 char *const * 的转换有效。请参阅底部的解释链接。
除了一件特定的事情之外,这一切都是有意义的。所以我有以下代码:
#include <stdio.h>
void
print(const char *const*param)
{
printf("%s\n", param[0]);
}
int
main(int argc, char **argv)
{
print(argv);
return 0;
}
如果我将它编译为 C++ 代码,它编译得非常好。但是,如果相同的代码仅编译为 C 代码,我会收到一个错误(好吧,一个警告,但假设 -Werror,即将警告视为错误)。
gcc:
test.c: In function ‘main’:
test.c:12:11: warning: passing argument 1 of ‘print’ from incompatible pointer type [-Wincompatible-pointer-types]
print(argv);
^
test.c:4:1: note: expected ‘const char * const*’ but argument is of type ‘char **’
print(const char *const*param)
^
叮当声:
test.c:12:11: warning: passing 'char **' to parameter of type 'const char *const *' discards qualifiers in nested pointer types [-Wincompatible-pointer-types-discards-qualifiers]
print(argv);
^~~~
test.c:4:25: note: passing argument to parameter 'param' here
print(const char *const*param)
^
这两种行为都独立于标准,也独立于编译器。我尝试了gcc 和clang 的各种标准。
这个查询有两个原因。首先,我想了解是否有区别,其次,我有一个函数对指针的任何层都不做任何事情,我需要它能够与 const char ** 以及 char *const * 和 @987654334 一起使用@。显式转换每个调用是不可维护的。而且我不知道函数原型应该是什么样子。
这是引发我好奇心的问题: Implicit conversion from char** to const char**
这是char ** => const char** 问题的另一个很好的解释:
http://c-faq.com/ansi/constmismatch.html
如果与此问题相关的链接令人困惑,请随时将其编辑掉。
【问题讨论】:
-
可以抑制无用的警告,在这种情况下使用
-Wno-incompatible-pointer-types(用于gcc)和-Wno-incompatible-pointer-types-discards-qualifiers(用于clang)(这就是警告消息显示激活它的警告标志的原因:所以如果它对你没有用,你可以压制它)。然后你可以继续-Werror没有问题。 -
@chrisjester-young 这不是他的问题如何抑制警告。
-
C 有一个更简单、更不灵活的类型系统。 C++ 有更强大的类型系统。就这样。 C 不能 允许这种转换没有技术原因。它可以。它根本没有。
-
@Olaf 不,C++ 允许从
Foo**转换为const Foo* const*。 -
@nert:“为什么?”的问题已经存在了很长时间。我也一直在寻找答案,但似乎这里唯一的答案是“它只是历史上发生的,没有人关心纠正这个问题”。我不知道为什么 C 不想在这种转换中采用 C++ 方法来实现 const 正确性。它不会破坏任何遗留代码。