简体   繁体   English

function参数声明中const指针和const数组类型的区别

[英]Difference between const pointer and const array type in function parameter declaration

If I try to compile this small example:如果我尝试编译这个小例子:

void f(const int *a) {
    int * ptr = a;
    *ptr = 1;
}

void g(const int a[]) {
    int * ptr = a;
    *ptr = 1;
}

I get a warning for function f and an error for function g .我收到 function f警告和 function g错误。 I tried with gcc 9.3.0 and clang 10.0.0 and got very similar messages.我尝试使用 gcc 9.3.0 和 clang 10.0.0 并得到非常相似的消息。 Here the one from gcc:这是来自 gcc 的一个:

main.c: In function ‘f’:
main.c:4:16: warning: initialization discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
    4 |     int* ptr = a;
      |                ^
main.c: In function ‘g’:
main.c:10:5: error: invalid operands to binary * (have ‘const int *’ and ‘int *’)
   10 |     *ptr = 1;
      |     ^

I know there is a difference between arrays and pointers, but I always believed there is no difference in function parameter declaration.我知道 arrays 和指针之间有区别,但我一直认为 function 参数声明没有区别。 And isn't using an array and a pointer as left hand operand in an assignment completely equivalent?并且在赋值中使用数组和指针作为左操作数不是完全等效的吗? After all I also thought that the following were interchangeable:毕竟我还认为以下是可以互换的:

int main(int argc, char * argv[])

int main(int argc, char ** argv)

My questions:我的问题:

  • What is the exact difference between const int * a and const int a[] in a function parameter declaration? function 参数声明中的const int * aconst int a[]之间的确切区别是什么?

  • Why do I get a warning in one of the cases and an error in the other?为什么我在其中一种情况下收到警告而在另一种情况下收到错误?

  • Shouldn't be both cases errors, because I try to change a const parameter?不应该是两种情况的错误,因为我尝试更改const参数?

Edit as Paul Hankin pointed out I missed a semicolon in the original code.编辑保罗汉金指出我错过了原始代码中的分号。 If added, both functions indeed give the same warning message, which is OK, since implicit pointer conversions (like in ptr = a discard const qualifiers.如果添加,这两个函数确实会给出相同的警告消息,这没关系,因为隐式指针转换(如ptr = a discard const qualifiers.

I get exactly the same messages for both functions in both gcc and clang.对于 gcc 和 clang 中的两个函数,我得到完全相同的消息。 You have some typo in the code and didn't make a copy/paste when you posted it here.您在代码中有一些拼写错误,并且在您将其发布到此处时没有进行复制/粘贴。

I always believed there is no difference in function parameter declaration.我一直认为 function 参数声明没有区别。

This is true for plain 1D arrays.这适用于普通的一维 arrays。 An array parameter such as const int a[] will get adjusted ("decay") into a pointer to it's first element.诸如const int a[]之类的数组参数将被调整(“衰减”)为指向其第一个元素的指针。 It is 100% equivalent to const int* a .它与const int* a 100% 等效。 Note that the const qualifier belongs to the pointed-at type, not the pointer itself.请注意, const qualifier属于指向类型,而不是指针本身。

Now as it happens, incomplete types such as arrays without a size cannot actually be used as function parameters if not for this array adjustment rule 1) .现在碰巧的是,如果没有此数组调整规则1) ,则不完整的类型(例如没有大小的 arrays)实际上不能用作 function 参数。 It's the very reason why you can even type out an incomplete array type [] without size as a function parameter, because the type gets adjusted before the size of the array matters and the result is not an incomplete type but a pointer (to a complete type).这就是为什么您甚至可以输入不完整的数组类型[]作为 function 参数的原因,因为在数组大小重要之前调整类型并且结果不是不完整的类型而是指针(指向完整的类型)。

This equivalence doesn't scale well to 2D arrays however.但是,这种等效性不能很好地扩展到 2D arrays。 An array parameter such as const int a[x][y] is an array of arrays. const int a[x][y]等数组参数是 arrays 的数组。 The first item is of array type const int[y] .第一项是数组类型const int[y] So it gets adjusted to a pointer to such a type:所以它被调整为指向这种类型的指针:
const (*int)[y] . const (*int)[y] This is not compatible with const int* nor with const int** .这与const int*const int**兼容。


1) C17 6.7.6.3 1) C17 6.7.6.3

After adjustment, the parameters in a parameter type list in a function declarator that is part of a definition of that function shall not have incomplete type.调整后,作为 function 定义的一部分的 function 声明符中的参数类型列表中的参数不应具有不完整类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM