Зачем приводить ноль к типу указателя и получать доступ к работе его члена? - PullRequest
2 голосов
/ 03 февраля 2020

Недавно я увидел что-то классное.

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

По сути, я знаю, что делает этот макрос. Но есть одна вещь, которую я не могу понять.

Почему мы можем привести 0 в тип указателя (struct) и получить доступ к его члену? Я уже сослался на некоторые подобные вещи, а 0 выглядит как нулевой указатель. Так почему же мы можем привести нулевой указатель и затем получить доступ к его члену?

Ответы [ 2 ]

3 голосов
/ 03 февраля 2020

typeof это расширение cc. Результатом этого оператора является имя типа.

Это работает, потому что его операнд вычисляется во время компиляции, поэтому указатель фактически не должен указывать на что-либо. Документация для этого оператора гласит:

Операнд typeof оценивается на предмет его побочных эффектов, если и только если он является выражением изменяемого типа или именем такой тип.

Поскольку struct не может содержать массив переменной длины, это гарантирует, что typeof( ((type *)0)->member ) не будет оцениваться во время выполнения, поэтому это безопасная операция.

0 голосов
/ 03 февраля 2020

В приведенном вами примере кода приведено значение 0 в пределах typeof. Но typeof это не функция, это оператор. Вы получаете доступ к его типу, а не к его значению.

Ссылка на этот вопрос: Почему typeof null "объект"?

...