Когда я применяю макрос container_of
к структуре C, содержащей массив символов, я получаю предупреждение: инициализация из несовместимого типа указателя.
Вот коды:
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
struct st {
int a;
char b;
char c[16];
void *p;
};
int main(void)
{
struct st t = {
.a = 101,
.b = 'B',
.c = "hello",
.p = NULL
};
char (*p)[16] = &t.c;
struct st *s = container_of(p, struct st, c);
return 0;
}
Кажется, что тип __mptr
- это []
, который выводится typeof()
. Однако сам ptr
имеет тип (*)[]
. Очевидно, что они не одинаковы.
Кроме того, если я скомпилирую этот код с помощью clang, все будет в порядке. GCC, кажется, имеет более строгое правило для проверки типов.
Q: Как исправить это предупреждение?
(*)[]
не является типом, и[]
тоже. - person too honest for this site   schedule 10.10.2016[]
обозначает тип массива, а(*)[]
обозначает указатель на массив. - person Douglas Su   schedule 10.10.2016CONTAINING_RECORD
, который, конечно, не использует никаких расширений GCC. - person Ian Abbott   schedule 10.10.2016container_of
из ядра Linux несколько несовершенен, но если вам нужно его использовать, и вы знаете, что элемент является массивом, вы можете использовать элемент массива вместо самого массива. т.е.char *p = &t.c[0]; struct st *s = container_of(p, struct st, c[0]);
- person Ian Abbott   schedule 10.10.2016container_of
ядра Linux практически не изменился с тех пор, как он впервые появился (в include/linux/kernel.h) в версии ядра Linux 2.5.28. - person Ian Abbott   schedule 10.10.2016