开发者

return from incompatible pointer type (const vs non-const). C/GCC

I have following piece of code:

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
}   

how do I fix this error? what am I doing wrong?

do I have to cast _my_array as (const array_t *)? Shouldn't cast from pointer to const pointe开发者_JAVA技巧r be implicit?

Note:

return _my_array;

works as well, i.e. compiles with the same warning.


The problem is the const; the function returns const array_t * (pointer to const array_t), but the returned expression, &_my_array, is of type array_t *, and the two types are not compatible.

The simplest fix is to drop the const from the return type:

typedef uint8_t array_t[8];
static array_t _my_array;
static array_t * foo(void) {
    return &_my_array;
}

EDIT:

I'm hesitant to suggest a compiler bug, but I've come up with a test program that I think indicates either a bug in gcc or a very obscure aspect of the C standard.

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;
}

When I compile this with gcc -c -std=c99 -pedantic-errors c.c (gcc 4.5.2), I get:

c.c: In function ‘that_func’:
c.c:12:5: error: return from incompatible pointer type

Why does it complain about an implicit conversion from that_type* to const that_type*, but not about a conversion from this_type* to const this_type*.

Since that_type is a typedef, it's an alias for an array type, and that_type* is a pointer to an array (not a pointer to an element of an array); there is no array-to-pointer conversion as far as I can tell. I don't think the fact that this_type is an integer type and that_type is an array type should make any difference.

Another data point: on Solaris 9, cc -c -Xc c.c doesn't complain.

Logically, converting a pointer to foo to a pointer to const foo should be safe; it doesn't produce any opportunity to violate const-correctness.

If I'm right, then the code in the question is valid, gcc's warning is incorrect, and you can work around it either by dropping the const on the function definition (make it return array_t* rather than const array_t*, or by adding a cast on the return statement:

return (const array_t*)&_my_array;

If I'm wrong, I expect someone will point it out soon.

(My use of this, a C++ keyword, as an identifier is somewhat deliberate. This is a C question. I understand that C++ has slightly different rules in this area.)

EDIT2: I've just submitted a gcc bug report.

EDIT3: Joseph S. Myers responded to my bug report:

This is not a bug. You can implicitly convert "pointer to int" to "pointer to const int", but not "pointer to array of int" to "pointer to array of const int" (see 6.5.16.1), and "const that_type *" is "pointer to array of const int" (there is no such type as "pointer to const array of int", which would be a permitted target of such a conversion; see 6.7.3#8).


Answered by Joseph S. Myers

This is not a bug. You can implicitly convert "pointer to int" to "pointer to const int", but not "pointer to array of int" to "pointer to array of const int" (see 6.5.16.1), and "const that_type *" is "pointer to array of const int" (there is no such type as "pointer to const array of int", which would be a permitted target of such a conversion; see 6.7.3#8).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜