我可以传递伪装成数组的常量指针吗?
void foo(const char *s);
相当于:
void foo(const char s[]);
是否有与以下两个类似的等价物?
void foo(char * const s);
void foo(const char * const s);
void foo(const char *s);
is equivalent to:
void foo(const char s[]);
Are there similar equivalents to the following two?
void foo(char * const s);
void foo(const char * const s);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在 C++ 中,编译器会自动将 T 类型 N 个元素的数组(其中
N
可以未知)类型的函数参数转换为 >指向 T 的指针。在同一转换中,参数的顶级 const 限定符被删除:这意味着在指针的情况下,顶级 const 限定符被删除,而在数组的情况下,它被转换为指向的指针。现在,另一方面,您不能混合两者,只是因为您不能声明一个 T 类型的 N 个元素的常量数组,因为数组始终是 const。这意味着你不能写:
因为参数的类型无效。如果它是有效类型,则将应用转换,但由于它不是有效类型,编译器将在尝试执行转换之前拒绝该代码。
这在 C++03 标准的 §8.3.5/3 中进行了处理(可能在 C++11 中接近的地方)
请注意,由于编译器将执行该转换,因此最好遵循最小意外原则编写编译器将使用的实际类型:
编译器不会检查传递的数组是否有 10 个元素,它会将声明读取为
void f( int * )
,并且很乐意接受包含较少元素的数组甚至根本没有数组(指向单个 int 的指针)的调用。在实际代码中使用指针:可能会在代码审查中触发一些警报:我们是否保证在对
f
的所有调用中参数至少有 6 个元素大?为了以防万一,我们不应该也传递尺寸吗?In C++, the compiler will automatically convert function parameters of type array of N elements of type T (where
N
can be unknown) into pointer to T. In the same transformation top levelconst
qualifiers for the arguments are dropped:That means that in the pointer case, the top level const qualifier is removed, and in the case of the array it is converted to pointer to. Now, on the other hand you cannot mix both, only because you cannot declare a constant array of N elements of type T, since arrays are always const. That means that you cannot write:
As the type of the parameter is invalid. If it was a valid type, then the conversions would apply, but because it is not, the compiler will reject the code before trying to perform the conversion.
This is treated in §8.3.5/3 of the C++03 standard (and probably somewhere close in C++11)
Note that since the compiler will perform that conversion, it is better to write the actual type that is going to be used by the compiler, following the principle of least surprise:
The compiler is not going to check that the passed array has 10 elements, it reads the declaration as
void f( int * )
, and will gladly accept a call with an array of less elements or even no array at all (a pointer to a single int). Using a pointer in the actual code:Will likely trigger some alarms in a code review: are we guaranteed that in all calls to
f
the argument will be at least 6 elements big? Should we not pass also the size just in case?在 C89 中不能,但在 C99 中您可以将等价物声明为:
You cannot in C89, but in C99 you can declare the equivalents as:
这在某些情况下很有用:
在 C 中:
this will be useful in some cases:
and in C:
我认为指针可以为空,而数组参数不能为空(并且允许编译器在知道这一点的情况下进行优化;但是在一个简单的示例中,gcc-4.6 不会进行此类优化,即使使用 -O3 也是如此)。
我期望编译器会对下面的两个函数进行不同的优化。事实并非如此。我手头没有 C 标准来检查它是否可以删除下面 ss 中的测试。
I thought that a pointer can be null, while an array argument cannot be null (and that the compiler is permitted to optimize knowing that; however on a simple example gcc-4.6 don't do such an optimization, even with -O3).
I am expecting that the compiler would optimize differently the two functions below. It does not. I don't have my C standard at hand to check if it could remove the test in ss below.