简体   繁体   English

将结构传递给 `const struct` 类型的参数不会产生警告

[英]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?我在这里缺少什么?

Converting Pointers转换指针

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 ,则结构成员dataconst ,但该成员是指针。 So this just means the pointer is const .所以这只是意味着指针const That does not mean what it points to is const .这并不意味着它指向的const

Footnote脚注

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.

相关问题 解决警告:将“ const void *”传递给类型“ AV *”的参数 - Solve warning: passing 'const void *' to parameter of type 'AV *' 为什么以这种方式传递结构会产生段错误? - Why does passing a struct in this way produce a segfault? 警告:不兼容的指针类型将“char *”传递给“FILE *”类型的参数(又名“struct __sFILE *”) - warning: incompatible pointer types passing 'char *' to parameter of type 'FILE *' (aka 'struct __sFILE *') 用const运算符警告(在struct中) - warning with const operator (in struct) 将“void”传递给不兼容类型“const char *”的参数? - Passing 'void' to parameter of incompatible type 'const char *'? 将非const参数传递给需要const参数的函数时发出警告。 有没有更好的办法? - Warning when passing non-const parameter to a function that expects const parameter. Is there a better way? 警告将“ char []”传递给“ unsigned char *”类型的参数 - Warning passing 'char []' to parameter of type 'unsigned char *' C 中的 const 结构参数 - const Struct parameter in C 为什么将 char** 作为 const char** 传递会产生警告? - Why does passing char** as const char** generate a warning? 为什么gcc不会为int和char产生类型不匹配警告? - Why gcc does not produce type mismatch warning for int and char?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM