gpt4 book ai didi

c - 动态结构数组和函数调用 f(const struct_type *const data[])

转载 作者:太空宇宙 更新时间:2023-11-04 02:20:20 25 4
gpt4 key购买 nike

以下代码警告类型不兼容。解决此代码的正确方法是什么?

谢谢

typedef struct a_struct struct_type;

void f(const struct_type *const data[], unsigned n);

void test(unsigned n)
{
struct_type **v;

assert(n);
v = malloc(n * sizeof(struct_type *));
/* fill v with new struct_type (with a malloc per entry) */
f(v, n); <- WARN on v
}

最佳答案

编译器提示的原因是 f 声明中的第一个 const

尝试使用

void f(struct_type *const data[], unsigned n);
/*...*/
f( v, n );

并且您不会收到相同的警告。或者,您可以在调用 f

时转换 v
void f(const struct_type *const data[], unsigned n);
/*...*/
f( (const struct_type * const *) v, n );

这有点违反直觉,但在 C 中,您不能将 pointer-to-pointer-to-nonconst 传递给 pointer-to-pointer-to-const。他们做了一个特殊的异常(exception),允许您将 pointer-to-nonconst 传递给 pointer-to-const

这是一个常见问题 "Why can't I pass a char ** to a function which expects a const char **?" :

You can use a pointer-to-T (for any type T) where a pointer-to-const-T is expected. However, the rule (an explicit exception) which permits slight mismatches in qualified pointer types is not applied recursively, but only at the top level. (const char ** is pointer-to-pointer-to-const-char, and the exception therefore does not apply.)

The reason that you cannot assign a char ** value to a const char ** pointer is somewhat obscure. Given that the const qualifier exists at all, the compiler would like to help you keep your promises not to modify const values. That's why you can assign a char * to a const char *, but not the other way around: it's clearly safe to add const-ness to a simple pointer, but it would be dangerous to take it away. However, suppose you performed the following more complicated series of assignments:

const char c = 'x';     /* 1 */
char *p1; /* 2 */
const char **p2 = &p1; /* 3 */
*p2 = &c; /* 4 */
*p1 = 'X'; /* 5 */

In line 3, we assign a char ** to a const char **. (The compiler should complain.) In line 4, we assign a const char * to a const char *; this is clearly legal. In line 5, we modify what a char * points to--this is supposed to be legal. However, p1 ends up pointing to c, which is const. This came about in line 4, because *p2 was really p1. This was set up in line 3, which is an assignment of a form that is disallowed, and this is exactly why line 3 is disallowed.

Assigning a char ** to a const char ** (as in line 3, and in the original question) is not immediately dangerous. But it sets up a situation in which p2's promise--that the ultimately-pointed-to value won't be modified--cannot be kept.

(C++ has more complicated rules for assigning const-qualified pointers which let you make more kinds of assignments without incurring warnings, but still protect against inadvertent attempts to modify const values. C++ would still not allow assigning a char ** to a const char **, but it would let you get away with assigning a char ** to a const char * const *.)

In C, if you must assign or pass pointers which have qualifier mismatches at other than the first level of indirection, you must use explicit casts (e.g. (const char **) in this case), although as always, the need for such a cast may indicate a deeper problem which the cast doesn't really fix.

References: ISO Sec. 6.1.2.6, Sec. 6.3.16.1, Sec. 6.5.3 H&S Sec. 7.9.1 pp. 221-2

关于c - 动态结构数组和函数调用 f(const struct_type *const data[]),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/847772/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com