我有一个整数数组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
的原因)。
答案 0 :(得分:3)
只要这样做:
#include <stdio.h>
// note can also use "const int foo[3]" but in that
// case 3 is nothing more than a comment for a reader
void print_foo(const int foo[])
{
// Print the second integer
printf("%d\n", foo[1]);
}
int main()
{
int foo[3] = {1, 2, 3};
print_foo(foo);
}
该数组已经由地址给出
答案 1 :(得分:2)
有趣的是,我可以在没有警告的情况下使用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;
}
在我的32位系统上,输出为2 - 12
,这证明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在其约束中说明了简单赋值:
应满足以下条件之一:
...
左操作数具有原子,合格或不合格的指针类型,并且(考虑到左操作数在左值转换后将具有的类型)两个操作数都是指向兼容类型的合格或不合格版本的指针,并且左侧指向的类型具有全部右侧指向的类型的限定词
好的,即使不兼容,也可以将int (*)[3]
分配给int (const *)[3]
。
但是int [3]
和const int[3]
是不同的类型,因此无法将int (*)[3]
分配给const int (*)[3]
或const int (const *)[3]
。
您想要的东西是有道理的,但是我无法想象用一种一致的方式声明它。