[英]Passing structure to parameter of type `const struct` does not produce a warning
In the following example not-const qualified pointer b
is passed to func
, which expects a pointer to a const qualified type.在下面的示例中,非 const 限定指针
b
被传递给func
,它需要一个指向 const 限定类型的指针。 Hence, I would expect the compiler to issue a warning.因此,我希望编译器发出警告。 However, if I compile this program with clang and
-Wall -Wextra -pedantic
there is no warning.但是,如果我用 clang 和
-Wall -Wextra -pedantic
编译这个程序,就没有警告。 Why is that?这是为什么?
#include <stdlib.h>
#include <string.h>
#define N 5
struct Bear {
int n;
int v;
int *data;
};
void func (const struct Bear *bear, int *data, const size_t n)
{
memcpy (bear->data, data, n);
}
int main (void)
{
int arr[N];
int *mem = malloc (N*sizeof (int));
if (mem == NULL) return -1;
struct Bear *b = &(struct Bear){1, 2, mem};
func (b, arr, N);
free (mem);
return 0;
}
Moreover, if I change the line in which the structure is initialized to此外,如果我将结构初始化的行更改为
const struct Bear *b = &(const struct Bear){1, 2, mem};
there is still no warning.仍然没有警告。 I understand that
const
in a struct declaration is applied to its fields, hence, bear->v = 11;
我知道结构声明中的
const
应用于其字段,因此, bear->v = 11;
in func
is clearly an error (and produces a warning). in
func
显然是一个错误(并产生警告)。 However, this does not seem to be true for pointers.但是,对于指针来说,这似乎并非如此。
Is this undefined behavior?这是未定义的行为吗? What am I missing here?
我在这里缺少什么?
When calling a function with a prototype, the argument ( b
, of type struct Bear *
) is converted to the type of the corresponding parameter ( bear
, of type const struct Bear *
), per C 2018 6.5.2.2 7:当调用带有原型的函数时,根据 C 2018 6.5.2.2 7,参数(
b
,类型为struct Bear *
)被转换为相应参数的类型( bear
,类型为const struct Bear *
):
If the expression that denotes the called function has a type that does include a prototype, the arguments are implicitly converted, as if by assignment, to the types of the corresponding parameters…
如果表示被调用函数的表达式的类型确实包含原型,则参数将隐式转换,就像通过赋值一样,转换为相应参数的类型……
The constraints for assignment in 6.5.16.1 1 include allowing conversion to a pointer to the same type but with added qualifiers such as const
: 6.5.16.1 1 中的赋值约束包括允许转换为指向相同类型的指针,但添加了诸如
const
限定符:
… the left operand has atomic, qualified, or unqualified pointer type, and … both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right…
... 左操作数具有原子、限定或非限定指针类型,并且 ... 两个操作数都是指向兼容类型的限定或非限定版本的指针,左侧指向的类型具有右侧指向的类型的所有限定符......
Also, conversions of pointers are discussed in C 2018 6.3.2.3, where paragraph 2 says:此外,在 C 2018 6.3.2.3 中讨论了指针的转换,其中第 2 段说:
For any qualifier q , a pointer to a non- q -qualified type may be converted to a pointer to the q -qualified version of the type…
对于任何限定符q ,指向非q限定类型的指针可以转换为指向该类型的q限定版本的指针......
Quite simply, the qualifiers are restrictions on the use of a thing;很简单,限定词是对事物使用的限制; they say it is intended for some subset of potential uses of the thing.
他们说它旨在用于该事物的某些潜在用途的子集。 The
const
qualifier says the object will be used only to read its value, not to modify its value. const
限定符表示该对象将仅用于读取其值,而不是修改其值。 1 So it is perfectly fine to pass a pointer to a thing that may be modified to a function that indicates it will not modify it. 1因此,将指向可能被修改的事物的指针传递给指示它不会修改它的函数是完全没问题的。 So the rules of the C standard are written to permit this.
所以编写 C 标准的规则是为了允许这样做。
const
Applied to Structures const
应用于结构I understand that const in a struct declaration is applied to its fields…
我知道结构声明中的 const 应用于其字段......
If the structure is const
, the structure member data
is const
, but that member is a pointer.如果结构是
const
,则结构成员data
是const
,但该成员是指针。 So this just means the pointer is const
.所以这只是意味着指针是
const
。 That does not mean what it points to is const
.这并不意味着它指向的是
const
。
1 The const
qualifier is not a complete barrier to modifying an object. 1
const
限定符并不是修改对象的完全障碍。 If an object was defined without const
, a pointer to it for which const
has been added can be converted (with a cast) back to a pointer without const
and used to modify the object.如果对象不经定义
const
,指向它的指针为其中const
已被添加可以被转换(带铸)回指针而不const
和用于修改对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.