2013-07-16 3 views
3

Это одна из серии макросов в stddef.h.Что делает (s *) 0 in (size_t) & (((s *) 0) -> m) mean

#define offsetof(s,m) (size_t)&(((s *)0)->m) 

Что означает (ы) 0 означает?

+0

http://en.wikipedia.org/wiki/Offsetof – billz

+0

Следует отметить, что поведение этого не определено, и вы не должны использовать этот вид в своей программе. Некоторые компиляторы реализуют offsetof со встроенным. –

+0

Просто для пояснения: поведение 'offsetof (type, member)' определяется стандартом C++ (C++ 11 18.2/4), но только когда 'type' является * стандартным макетом * типа и' member' относится к нестатическому элементу данных. Эта конкретная реализация 'offsetof' основана на поведении, которое не определено стандартом, а конкретной реализацией C++. Другими словами, использование 'offsetof' в вашем коде совершенно нормально, но разыменование указателя NULL в вашем коде - как это делает реализация' offsetof' - не переносима. – Casey

ответ

7

Это способ записи указателя NULL типа pointer-to-s. Принимая адрес m члена s, адрес которого равен 0, вы получаете смещение m в пределах s.

+0

BTW, не '((s *) 0) -> m' invoke undefined behavior? – Nawaz

+1

@Nawaz: Но это имеет очень четкое поведение: оно дает вам «объект» m, который является членом структуры s, которая находится в ячейке памяти 0. Неопределенным поведением будет любой доступ для чтения или записи м или с. (Наиболее вероятным поведением в этом неопределенном случае было бы нарушение доступа к памяти, что может привести к сбою программы немедленно - если ОС не запретит какой-либо доступ к этому диапазону адресов в памяти.) – comonad

+0

@ comonad: Я говорю от языковая точка зрения, а не то, что компилятор делает с вашим кодом. Я уверен, что язык этого не позволяет! – Nawaz

3

Это тип, преобразование 0 в pointer to s.

+0

Следует отметить, что вместо этого вы должны использовать 'static_cast' или одну из C++-трансляций. – Shoe

+1

@Jeffrey stddef.h используется как для C, так и для C++, поэтому он не использует специфические для C++ функции. – Barmar

0

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

+0

Надеюсь, имя типа структуры. – Barmar

0

Создать указатель типа s и с нулевым значением (Null)

0

s, как предполагается, имя типа здесь, такие как int, так (s*)0 в основном литье 0 к типу указателя.

0

0 - это не только целое число, но и нулевой указатель. Поэтому ((S*)0) отображает нулевой указатель на указатель на s (где s, вероятно, является структурой).

+1

В этом случае более важно то, что оно равно 0. Оно не используется как нулевой указатель. – Barmar

Смежные вопросы