我有以下代码:
typedef uint8_t array_t[8];
static array_t _my_array;
static const array_t * foo(void) {
return &_my_array; // <-- return from incompatible pointer type
}
如何修复此错误?我做错了什么?
我必须将_my_array转换为(const array_t *)
吗?不应该从指向const
指针的指针强制转换?
注意:
return _my_array;
将作为运行,即使用相同的警告进行编译。
答案 0 :(得分:2)
问题是const
;该函数返回const array_t *
(指向const array_t的指针),但返回的表达式&_my_array
的类型为array_t *
,并且这两种类型不兼容。
最简单的解决方法是从返回类型中删除const
:
typedef uint8_t array_t[8];
static array_t _my_array;
static array_t * foo(void) {
return &_my_array;
}
修改强>:
我对建议编译器错误犹豫不决,但我想出了一个测试程序,我认为它表示gcc中的错误或C标准的一个非常模糊的方面。
typedef int this_type;
typedef int that_type[8];
static this_type this;
static that_type that;
static const this_type *this_func(void) {
return &this;
}
static const that_type *that_func(void) {
return &that;
}
当我用gcc -c -std=c99 -pedantic-errors c.c
(gcc 4.5.2)编译时,我得到:
c.c: In function ‘that_func’:
c.c:12:5: error: return from incompatible pointer type
为什么会抱怨从that_type*
到const that_type*
的隐式转换,而不是从this_type*
到const this_type*
的转换。
由于that_type
是 typedef ,因此它是数组类型的别名,而that_type*
是指向数组的指针(不是指向数组元素的指针) );据我所知,没有数组到指针的转换。我不认为 this_type
是一个整数类型,而that_type
是一个数组类型应该有所不同。
另一个数据点:在Solaris 9上,cc -c -Xc c.c
没有抱怨。
逻辑上,将指向 foo 的指针转换为指向const foo 的指针应该是安全的;它不会产生违反常规正确性的任何机会。
如果我是对的,那么问题中的代码是有效的,gcc的警告是不正确的,你可以通过在函数定义上删除const
来解决它(让它返回{{1}而不是array_t*
,或者在return语句中添加一个强制转换:
const array_t*
如果我错了,我希望有人能尽快指出。
(我使用return (const array_t*)&_my_array;
,一个C ++关键字作为标识符有点慎重。这是一个C问题。我理解C ++在这方面的规则略有不同。)
<强> EDIT2:强> 我刚刚提交了gcc bug report。
<强> EDIT3:强> Joseph S. Myers回复了我的错误报告:
这不是错误。您可以隐式地将“指向int”转换为 “指向const int的指针”,但不是“指向int数组的指针”到“指针” to const int“(见6.5.16.1),”const that_type *“是 “指向const int数组的指针”(没有这样的类型作为“指向 const数组的int“,这将是这样一个允许的目标 转换;见6.7.3#8)。
答案 1 :(得分:1)
这不是错误。您可以隐式地将“指向int”转换为 “指向const int的指针”,但不是“指向int数组的指针”到“指针” to const int“(见6.5.16.1),”const that_type *“是 “指向const int数组的指针”(没有这样的类型作为“指向 const数组的int“,这将是这样一个允许的目标 转换;见6.7.3#8)。