2010-08-10 3 views
0

В исходном коде qemu у меня есть следующий макрос с именем offsetof. Может ли кто-нибудь сказать мне, что он делает?Что делает следующий макрос?

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER) 

Он используется таким образом:

offsetof(CPUState, icount_decr.u32) 

где CPUState является структурой.

Я думаю, что это дает смещение члена внутри структуры, но я не уверен.

EDIT: Да, я узнал, что происходит. У определения CPUState был макрос внутри, который я пропустил, включая переменную icount_decr.

+1

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

+1

Макрос технически запускает неопределенное поведение, но, случается, работает во многих местах. Современный (например, GCC 4) '' определит его компилятору, чтобы избежать неопределенности, а также некоторых головных болей на C++. – zwol

+0

@ Zack: Как я уже сказал в ответ, это функция библиотеки, поэтому нет, это не неопределенное поведение. Внедрение может свободно реализовать его, но они хотят. (По сути, эта конкретная реализация заставляет определять адрес разыменованного нулевого указателя для конкретного компилятора.) – GManNickG

ответ

1

Ваше мнение верное! И название макроса дает хороший намек. ;)

3

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

+0

Компиляторы C/C++ в последнее время добавили для этого встроенную функцию, главным образом потому, что вы можете разбить эту технику с перегруженными операторами на C++, но также и потому, что она * является технически неопределенным поведением, и вы можете представить достаточно агрессивные точки - Это. – zwol

+0

@ Zack: Это библиотека, поэтому нет, это не неопределенное поведение. Внедрение может свободно реализовать его, но они хотят. – GManNickG

+1

Он подразумевает, что этот макрос определен внутри прикладной программы, и в этом случае это неопределенное поведение (хотя, скорее всего, будет работать, как ожидается, конечно). Если определение было в стандартной библиотеке, то оно, конечно, не было бы неопределенным. – jcoder

0

Это определено в 7.17/3:

offsetof(type, member-designator)
, которая расширяется к константным выражением целого, которое имеет тип size_t, величина которой смещение в байтах, к элементу структуры (обозначенный по член-обозначение), с начала его конструкции (обозначается тип). Обозначение типа и члена должно быть таким, чтобы данное выражение
static type t;
затем выражение &(t.member-designator) оценивает постоянную адреса. (Если указанный член битовое поле, поведение не определено.)

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

Таким образом, результатом этой конкретной реализации является не неопределенное поведение, поскольку вы не должны заботиться о том, как это реализовано. (Другими словами, ваша реализация делает гарантию того, что определение адреса косвенного нулевого указателя является корректным. Конечно, вы не можете этого сделать в своих собственных программах.)

Если в какой-то библиотеке есть (re) определены offsetof, они сделали ваше поведение программы неопределенным и вместо этого должны использовать стандартную библиотеку. (Манекены.)

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