从不兼容的指针类型返回(const与非const)。 C / GCC

时间:2011-10-07 18:19:54

标签: c gcc

我有以下代码:

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;

作为运行,即使用相同的警告进行编译。

2 个答案:

答案 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)

Answered by 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)。