макрос container_of не работает для char * или членов массива - PullRequest
0 голосов
/ 02 января 2019

Я читаю разработку драйверов устройств Linux от Джона Мэдиу, и один из них говорит:

The container_of macro won't work for char * or array members. It
means the first member of container_of must not be a pointer to
another pointer to char nor to array in the structure.

Это определение container_of:

#define container_of(ptr, type, member) ({ \
                const typeof( ((type *)0)->member ) *__mptr = (ptr); 
                (type *)( (char *)__mptr - offsetof(type,member) );})

Так что, если у меня есть

struct person {
int age;
int salary;
char *name;
} me;

а у меня char ** my_name = &(me.name);, почему я не могу сделать следующее:

struct person * me = container_of(my_name,struct person,name);

1 Ответ

0 голосов
/ 02 января 2019

Это связано с правилами ISO C по инициализации указателя, которые нарушают инициализацию __mptr для этого случая.

Вот урезанный пример:

int main()
{
    char ar[5] = {0};
    const char (*ptr)[5] = &ar;
}

// warning: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic]

( живое демо )

Существует обсуждение этой проблемы на предыдущем вопросе SO . Обратите внимание, что C ++ не имеет такого ограничения ; const может быть добавлен свободно.

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

...