C: лучший способ сделать sizeof (((SomeStruct *) 0) - > some_member)?

StackOverflow https://stackoverflow.com/questions/1014750

  •  06-07-2019
  •  | 
  •  

Вопрос

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

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
Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

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

Я не вижу причин делать что-то другое.

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

RTL_SIZEOF_THROUGH_FIELD()
RTL_CONTAINS_FIELD()

и отличный:

CONTAINING_RECORD() 

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top