возврат из несовместимого типа указателя (const против non-const).С / GCC - PullRequest
3 голосов
/ 07 октября 2011

У меня есть следующий фрагмент кода:

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 ]

2 голосов
/ 08 октября 2011

Проблема в 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;
}

EDIT :

Я не решаюсь предложить ошибку компилятора, но я придумал тестпрограмма, которая, как мне кажется, указывает либо на ошибку в 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 должно быть безопасным;это не дает возможности нарушить const -корректность.

Если я прав, то код в вопросе действителен, предупреждение gcc неверно, и вы можете обойти это, либо нажав const в определении функции (сделайте так, чтобы она возвращала array_t* вместо const array_t*, или добавив приведение в оператор return:

return (const array_t*)&_my_array;

Если я ошибаюсь, я ожидаю, что кто-то укажет на этоскоро.

(Мое использование this, ключевого слова C ++, в качестве идентификатора несколько преднамеренное. Это вопрос C. Я понимаю, что в C ++ есть немного другие правила в этой области.)

EDIT2: Я только что отправил gcc отчет об ошибке .

EDIT3: Джозеф С. Майерс ответил на мой отчет об ошибке:

Это не ошибка. Вы можете неявно преобразовать «указатель на int» в «указатель на const int», но не «указатель на массив int» на «указатель на массив const int»"(см. 6.5.16.1), а" const that_type * "является" указателем на массив const int "(существует no такой тип, как «указатель на константный массив типа int», который будет разрешенной целью такого преобразования;см. 6.7.3 # 8).

1 голос
/ 21 октября 2011

Ответ от Джозефа С. Майерса

Это не ошибка. Вы можете неявно преобразовать «указатель на int» в указатель на const int, но не указатель на массив целых указателей в массив const int "(см. 6.5.16.1), а" const that_type * " «указатель на массив const int» (такого типа как «указатель на const массив int ", который будет разрешенной целью такого преобразование; см. 6.7.3 # 8).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...