Это одна из серии макросов в stddef.h.Что делает (s *) 0 in (size_t) & (((s *) 0) -> m) mean
#define offsetof(s,m) (size_t)&(((s *)0)->m)
Что означает (ы) 0 означает?
Это одна из серии макросов в stddef.h.Что делает (s *) 0 in (size_t) & (((s *) 0) -> m) mean
#define offsetof(s,m) (size_t)&(((s *)0)->m)
Что означает (ы) 0 означает?
Это способ записи указателя NULL
типа pointer-to-s
. Принимая адрес m
члена s
, адрес которого равен 0, вы получаете смещение m
в пределах s
.
BTW, не '((s *) 0) -> m' invoke undefined behavior? – Nawaz
@Nawaz: Но это имеет очень четкое поведение: оно дает вам «объект» m, который является членом структуры s, которая находится в ячейке памяти 0. Неопределенным поведением будет любой доступ для чтения или записи м или с. (Наиболее вероятным поведением в этом неопределенном случае было бы нарушение доступа к памяти, что может привести к сбою программы немедленно - если ОС не запретит какой-либо доступ к этому диапазону адресов в памяти.) – comonad
@ comonad: Я говорю от языковая точка зрения, а не то, что компилятор делает с вашим кодом. Я уверен, что язык этого не позволяет! – Nawaz
Это отлит к указателю s
. s
в этом случае является одним аргументом макроса и, надеюсь, имя типа.
Надеюсь, имя типа структуры. – Barmar
Создать указатель типа s
и с нулевым значением (Null)
s, как предполагается, имя типа здесь, такие как int
, так (s*)0
в основном литье 0
к типу указателя.
0
- это не только целое число, но и нулевой указатель. Поэтому ((S*)0)
отображает нулевой указатель на указатель на s
(где s
, вероятно, является структурой).
В этом случае более важно то, что оно равно 0. Оно не используется как нулевой указатель. – Barmar
http://en.wikipedia.org/wiki/Offsetof – billz
Следует отметить, что поведение этого не определено, и вы не должны использовать этот вид в своей программе. Некоторые компиляторы реализуют offsetof со встроенным. –
Просто для пояснения: поведение 'offsetof (type, member)' определяется стандартом C++ (C++ 11 18.2/4), но только когда 'type' является * стандартным макетом * типа и' member' относится к нестатическому элементу данных. Эта конкретная реализация 'offsetof' основана на поведении, которое не определено стандартом, а конкретной реализацией C++. Другими словами, использование 'offsetof' в вашем коде совершенно нормально, но разыменование указателя NULL в вашем коде - как это делает реализация' offsetof' - не переносима. – Casey