有关将指针赋值给 const 指针的警告

问题描述 投票:0回答:1
char a = 0;
char b[20] = {0};
char c[][20] = {{0}};

const char *aPtr;
const char *bPtr;
const char (*cPtr)[20];
char (*dPtr)[20];


void test(void)
{
    aPtr = &a;
    bPtr = b;
    dPtr = &b;
    dPtr = c;

    cPtr = c;    // warning here

}

cPtr = &c; 只有这行代码生成了警告。

../source/bsw/user/PackParam_user.c:21:10: warning: assignment from incompatible pointer type
     cPtr = c;
          ^ 

我想了解为什么此特定代码行会出现此警告,而其他赋值语句不会触发任何警告。

我使用gcc v4.9

c pointers gcc-warning const-pointer
1个回答
0
投票

此编译器消息是由于 C 标准中与数组及其元素的

const
相关的缺陷所致。

当将一个指针分配给另一个指针时,无论有或没有限定符,都不指向

void
,C 2018 6.5.16.1 1 中的约束是:

…两个操作数都是指向兼容类型的限定或非限定版本的指针,并且左边指向的类型具有右边指向的类型的所有限定符…

cPtr = c;
中,
c
的类型为
char [1][20]
,并且它会自动转换为指向其第一个元素的指针,因此结果类型为
char (*)[20]
。它是一个指向
char [20]
类型的指针。

cPtr
的类型为
const char (*)[20]
。它是一个指向
const char [20]
的指针。

C 2018 6.7.6.2 6 告诉我们“要使两个数组类型兼容,两者都应具有兼容的元素类型……”但是元素类型

const char
char
不兼容,因为 6.7.3 11 说“对于两个限定类型要兼容,两者都应具有兼容类型的相同限定版本……”因此
char [20]
const char [20]
不是兼容类型。

现在您可能会说

const char [20]
具有
char [20]
的所有限定符,并且赋值约束允许在指针指向兼容类型时进行赋值,但操作数所指向的类型具有更多限定符。但是,
const
修改元素类型
char
,而不是指向的类型,即 20
char
数组。该约束允许将“指向 20
char
数组的指针”分配给“指向
const
20
char
数组的指针”。但这些不是涉及的类型。

他们应该是所涉及的类型。这是C标准的一个缺陷。 20 个

const char
的数组应该与 20 个
const
char
数组相同。如果数组元素是
const
,则数组本身实际上也是
const
——任何修改数组的尝试都是修改其元素的尝试,反之亦然。数组它的元素,因此数组和元素的标识符应该是一回事。但为此编写规则很复杂,并且直到 2018 年 C 标准中还没有完成。

C 标准尝试处理数组上的限定符。您可以尝试使用

cPtr
:
const
来使
char
成为指向 20 个
typedef
typedef char CharArray[20]; const CharArray *cPtr;
数组的指针。然而,C 2018 6.7.3 10 魔术般地去掉了这个限定符,将其从数组移动到元素:“如果数组类型的规范包含任何类型限定符,则元素类型是如此限定的,而不是数组类型......”回想起来,这是不够的,因为它没有解决数组限定符的问题。

编译器编写者意识到这是标准中的缺陷,并尝试解决它,这就是为什么 GCC 被修改为不发出此警告,除非

-pedantic
特别要求。

© www.soinside.com 2019 - 2024. All rights reserved.