C: лучший способ сделать sizeof (((SomeStruct *) 0) -> some_member)? - PullRequest
1 голос
/ 18 июня 2009

Я хочу получить размер определенного члена в структуре.

sizeof(((SomeStruct *) 0)->some_member) работает для меня, но я чувствую, что может быть лучший способ сделать это.

Я мог бы #define SIZEOF_ELEM(STRUCT, ELEM) sizeof(((STRUCT *) 0)->ELEM), а затем использовать SIZEOF_ELEM(SomeStruct, some_member), но мне интересно, есть ли уже что-то лучше встроенное.

Мой конкретный сценарий использования - hsc2hs (привязки на Haskell C).

pokeArray (plusPtr context (#offset AVFormatContext, filename)) .
  take (#size ((AVFormatContext *) 0)->filename) .
  (++ repeat '\NUL') $ filename

Ответы [ 4 ]

5 голосов
/ 18 июня 2009

То, что у вас есть, настолько чистое, насколько это возможно, если вы не можете гарантировать, что у вас есть переменная для разыменования. (Если вы можете, тогда, конечно, используйте только sizeof(var.member) или sizeof(ptr->member), но это не сработает в некоторых контекстах, где требуется постоянная времени компиляции.)

Когда-то давным-давно (около 1990 года) я столкнулся с компилятором, у которого 'offsetof' определен с использованием базового адреса 0, и он вышел из строя. Я обошел проблему, взломав <stddef.h>, чтобы использовать 1024 вместо 0. Но вы не должны сталкиваться с такими проблемами сейчас.

3 голосов
/ 19 июня 2009

У Microsoft в одном из заголовков есть следующее:

#define RTL_FIELD_SIZE(type, field) (sizeof(((type *)0)->field))

Не вижу смысла делать что-то другое.

Они связали макросы для:

RTL_SIZEOF_THROUGH_FIELD()
RTL_CONTAINS_FIELD()

и отличный:

CONTAINING_RECORD() 

, который помогает реализовать общие списки в прямом C, не требуя, чтобы поля ссылок были в начале структуры. Подробности смотрите в статье «Ядро горчицы» .

3 голосов
/ 18 июня 2009

В C ++ вы можете сделать sizeof (SomeStruct :: some_member), но это c, и у вас нет оператора разрешения области видимости. Насколько я знаю, вы написали настолько хорошо, насколько это возможно.

3 голосов
/ 18 июня 2009

Я полагаю, у вас уже есть правильное решение. Вы можете найти свой stddef.h и посмотреть, как определяется offsetof, так как он делает очень похожую вещь.

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

...