我有一个整数数组int foo[3]
,我想将它传递给另一个函数。我想完成两件事:
我定义的函数是:
void print_foo(const int(*const foo)[3]) {
// Print the second integer
printf("%d\n", (*foo)[1]);
}
我称之为:
int foo[3] = {1, 2, 3};
print_foo(&foo);
当我用 MinGW 的 gcc 编译它时,我收到警告:
warning: passing arg 1 of `print_foo` from incompatible pointer type
我想了解我做错了什么。
注意:我可以隐藏在没有第一个函数的情况下声明函数的警告const
:
void print_foo(int(*const foo)[3])
但这似乎是一种解决方法,因为我不仅希望指针地址保持不变,而且还希望内存的内容保持不变(这就是两者的原因const
)。
有趣的是,我可以使用 CLang 版本 3.4.1 和 6.0.0 编译以下代码而没有警告:
#include <stdio.h>
void print_foo(const int (* const foo)[3]) {
printf("%d - size: %lu\n", (*foo)[1], sizeof(*foo));
}
int main() {
int foo[3] = {1,2,3};
print_foo(&foo);
return 0;
}
输出2 - 12
在我的 32 位系统上,这证明它sizeof(*foo)
具有预期值。
但我会说 gcc 在这里是正确的,并且 Clang 允许它作为扩展。
标准(C11 的 n1570 草案)在 6.2.7 兼容类型和复合类型 §1 中说:
如果它们的类型相同,则两种类型具有兼容类型。确定两种类型是否兼容的附加规则在 6.7.2 类型说明符、6.7.3 类型限定符和 6.7.6 声明符和 6.7.3 类型限定符 § 10 中描述
对于兼容的两个限定类型,两者都应具有兼容类型的相同限定版本
因此类型需要具有相同的常量才能兼容。
但是在函数调用中传递参数与赋值具有相同的语义,并且 6.5.16.1 简单赋值在其约束中说:
以下之一应成立:
...
左操作数具有原子、限定或非限定指针类型,并且(考虑左操作数在左值转换后将具有的类型)两个操作数都是指向兼容类型的限定或非限定版本的指针,并且左侧指向的类型具有右侧指向的类型的所有限定符
这样就OK了,它允许一个分配int (*)[3]
到int (const *)[3]
即使他们不是兼容机。
但是int [3]
andconst int[3]
是不同的类型,因此您不能将 an 分配int (*)[3]
给 aconst int (*)[3]
或 a const int (const *)[3]
。
你想要什么是有道理的,但我无法想象一种一致的方式来声明它。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句