Избегайте предупреждения: ожидается «const struct aiocb * const *», но аргумент имеет тип «struct aiocb **» - PullRequest
2 голосов
/ 30 мая 2019
archives.c: In function ‘fd_writeback_wait’:
archives.c:121:21: warning: passing argument 1 of ‘aio_suspend’ from incompatible pointer type [-Wincompatible-pointer-types]
     r = aio_suspend(&cb, 1, NULL);
                     ^~~
In file included from ../lib/dpkg/fsys.h:28,
                 from ../lib/dpkg/triglib.h:28,
                 from archives.c:57:
/usr/include/aio.h:168:51: note: expected ‘const struct aiocb * const*’ but argument is of type ‘struct aiocb **’
 extern int aio_suspend (const struct aiocb *const __list[], int __nent,
                         ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~

Пояснения:

Я думаю, что нет способа избежать этогопредупреждение, без написания опасного приведения типа для изменения квалификаторов const, или подавление всей категории предупреждений.

Очевидно, C ++ здесь лучше.Он также имеет const_cast для более четкого приведения, что гарантирует, что вы только меняете квалификаторы const.

Другими словами, POSIX определяет aio_suspend () для использованияconst как это, возможно, довольно опасно.

Правильно ли я истолковал это?

Если я ошибаюсь, то как я могу избежать этого предупреждения, но все же проверить компилятором, что ятолько приведение const определителей, а не приведение к совершенно несовместимому типу?


Я подозреваю, что если есть методы, они не будут теми, которые я хотел бы использовать на практике, но мне любопытно.

Текущий код, над которым я работаю, явно не документирует требуемую версию компилятора.

Мне могут быть интересны методы, которые работают в стандартных версиях C.Мне было бы интересно услышать о расширениях GCC.Также приветствуются комментарии о том, рекомендуется или не рекомендуется определять параметры функций, подобные этому.

Читателям напоминается, что C и C ++ разные, а не 100% совместимых языков.Я признаю, что переключение баз кода на C ++ могло бы обеспечить решение, но я не думаю, что это решение было бы очень полезным для меня.Спасибо.

1 Ответ

2 голосов
/ 30 мая 2019

Вот способ вызова функции с соответствующей const ness:

struct aiocb cb;
const struct aiocb * cblist[1] = { &cb };
aio_suspend(cblist, 1, NULL);

И альтернативно:

struct aiocb cb;
const struct aiocb * cbptr = &cb;
aio_suspend(&cbptr, 1, NULL);

Обратите внимание, приведенный выше ответ был предложен, потому что вы использовали этот синтаксис:

r = aio_suspend(&cb, 1, NULL);

Передача адреса cb чему-то, что ожидает указатель на указатель, означает, что cb был указателем, поэтому этот вызов имеет смысл только для одного элемента массива.

Предположим, ваше предупреждение появилось, потому что у вас действительно было это:

struct aiocb *cbv[256];
r = aio_suspend(cbv, 256, NULL);

Предупреждение легко удалить. Используйте (void *).

r = aio_suspend((void *)cbv, 256, NULL);

Однако было бы лучше определить вектор, который будет использовать указатели на const.

const struct aiocb *cbv[256];
r = aio_suspend(cbv, 256, NULL);

Если каждый экземпляр обратного вызова действительно изменяем в действительности (например, был выделен malloc), то просто отмените const перед изменением.

struct aiocb *cb = (struct aiocb *)cbv[i];
/* ... modify cb ... */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...