Как указывает @litb и как показывает @JesperE, offsetof () предоставляет целочисленное смещение в байтах (как значение size_t
).
Когда вы могли бы использовать его?
Одним из случаев, когда это может иметь значение, является операция на основе таблицы для считывания огромного количества различных параметров конфигурации из файла и помещения значений в одинаково огромную структуру данных. Сокращая огромное до SO тривиальное (и игнорируя широкий спектр необходимых практических практик, таких как определение типов структуры в заголовках), я имею в виду, что некоторые параметры могут быть целыми числами, а другие - строками, и код может выглядеть слегка как *
#include <stddef.h>
typedef stuct config_info config_info;
struct config_info
{
int parameter1;
int parameter2;
int parameter3;
char *string1;
char *string2;
char *string3;
int parameter4;
} main_configuration;
typedef struct config_desc config_desc;
static const struct config_desc
{
char *name;
enum paramtype { PT_INT, PT_STR } type;
size_t offset;
int min_val;
int max_val;
int max_len;
} desc_configuration[] =
{
{ "GIZMOTRON_RATING", PT_INT, offsetof(config_info, parameter1), 0, 100, 0 },
{ "NECROSIS_FACTOR", PT_INT, offsetof(config_info, parameter2), -20, +20, 0 },
{ "GILLYWEED_LEAVES", PT_INT, offsetof(config_info, parameter3), 1, 3, 0 },
{ "INFLATION_FACTOR", PT_INT, offsetof(config_info, parameter4), 1000, 10000, 0 },
{ "EXTRA_CONFIG", PT_STR, offsetof(config_info, string1), 0, 0, 64 },
{ "USER_NAME", PT_STR, offsetof(config_info, string2), 0, 0, 16 },
{ "GIZMOTRON_LABEL", PT_STR, offsetof(config_info, string3), 0, 0, 32 },
};
Теперь вы можете написать общую функцию, которая читает строки из файла конфигурации, отбрасывая комментарии и пустые строки. Затем он изолирует имя параметра и ищет его в таблице desc_configuration
(которую вы можете отсортировать, чтобы можно было выполнить бинарный поиск - с этим обращаются несколько вопросов SO). Когда он находит правильную запись config_desc
, он может передать найденное значение и запись config_desc
одной из двух подпрограмм - одна для обработки строк, другая для обработки целых чисел.
Ключевая часть этих функций:
static int validate_set_int_config(const config_desc *desc, char *value)
{
int *data = (int *)((char *)&main_configuration + desc->offset);
...
*data = atoi(value);
...
}
static int validate_set_str_config(const config_desc *desc, char *value)
{
char **data = (char **)((char *)&main_configuration + desc->offset);
...
*data = strdup(value);
...
}
Это позволяет избежать написания отдельной функции для каждого отдельного члена структуры.