WikiSort.ru - Не сортированное

ПОИСК ПО САЙТУ | о проекте
Стандартная библиотека
языка программирования С

stddef.h — заголовочный файл стандартной библиотеки языка программирования С, определяющий макросы NULL и offsetof, а также типы ptrdiff_t, wchar_t и size_t.

Включение

Для использования заголовочного файла «stddef.h» в коде на языке C используется директива препроцессора:

#include <stddef.h>

Стандарт языка C++ определяет эквивалентный заголовочный файл «cstddef», подключаемый директивой:

#include <cstddef>

Пространство имён

Основное отличие «stddef.h» от «cstddef» заключается в том, что в «cstddef» определения типов размещены в пространстве имён std . То есть, в C++ определены std::size_t и std::ptrdiff_t вместо size_t и ptrdiff_t.

NULL

Константа #define препроцессора, обозначающая константный нулевой указатель и определённая одним из следующих способов (в зависимости от компилятора и языка).

#define NULL ((void*)0)
#define NULL 0
#define NULL 0L

offsetof(type, member)

Макрос препроцессора, определённый стандартом ANSI C и возвращающий значение типа size_t[1]. Макрос вычисляет смещение в байтах поля структуры или объединения от начала структуры или объединения[2].

Классическая реализация макроса работала с компиляторами, не проверяющими типы указателей, и основана на получении смещения поля структуры, размещёной в памяти по нулевому адресу:

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

Нулевой указатель преобразуется к указателю на структуру st. Затем оператор «&» получает адрес поля m указанной структуры.

Современные компиляторы реализуют макрос с помощью встроенных функций. Например, реализация gcc выглядит следующим образом[3]:

#define offsetof( st, m ) __builtin_offsetof( st, m )

Использование встроенной функции имеет несколько преимуществ. Например, для кода на C++ не вызывается перегруженный оператор «&»[4].

Макрос offsetof() позволяет писать код, работающий с разными структурами данных (см. обобщённое программирование). Например, в коде ядра ОС Linux с помощью offsetof() реализован макрос container_of() , получающий указатель на структуру по указателю на её поле[5]:

#define container_of( ptr, type, member ) \
   ( \
      { \
         const typeof( ((type *)0)->member ) *__mptr = (ptr); \
         (type *)( (char *)__mptr - offsetof( type, member ) ); \
      } \
   )
#include <stddef.h>
#include <stdio.h>

int main()
{
	struct car
	{
		char brand[31];
		char hp[30];
		double price;
		double tmp;
	} t;
	//смещение относительно начала.
	printf("%lu\n", offsetof(struct car, brand));
	printf("%lu\n", offsetof(struct car, hp));
	printf("%lu\n", offsetof(struct car, price));
	printf("%lu\n", offsetof(struct car, tmp));

	printf("\n");
	//размеры членов структуры
	printf("%lu\n", sizeof (t.brand));
	printf("%lu\n", sizeof (t.hp));
	printf("%lu\n", sizeof (t.price));
	printf("%lu\n", sizeof (t.tmp));

	// размер занимаемый структурой в памяти.
	printf("sizeof struct = %lu\n", sizeof(struct car)); 
	
}

В реализации используется оператор typeof() [6], не описанный в стандарте языка C. Пример использования макроса container_of() .

struct my_struct {
   const char * name;
   struct list_node list;
};

extern struct list_node * list_next ( struct list_node * );

void example () {
   struct list_node * current = /* ... */
   while ( current != NULL ) {
      struct my_struct * element = container_of( current, struct my_struct, list );
      printf( "%s\n", element->name );
      current = list_next( &element->list );
   }
}

В примере перебираются элементы связного списка, по указателю на поле list вычисляется указатель на структуру my_struct.

Тип size_t

Тип size_t беззнаковый, создан специально для хранения размера объектов любых типов и имеет достаточную для этого разрядность[7]. Разрядность зависит от платформы: на 32-битных платформах может составлять 32 бита, на 64-битных — 64 бита. Значения этого типа возвращают операторы sizeof() , _Alignof() и макрос offsetof. Максимальное значение равно SIZE_MAX (константа #define из файла «stdint.h»).

Стандарт POSIX определяет знаковый тип ssize_t (файл «unistd.h» для ОС UNIX или файл «stddef.h» для GNU C). Тип ssize_t является типом size_t со знаком. Комментарий в файле «sys/types.h» гласит, что ssize_t используется для подсчёта байт и выявления ошибок, может хранить значения по крайней мере от -1 до SSIZE_MAX .

Тип wchar_t

Тип wchar_t создан для хранения «широкого символа» (англ. wide character), определён в файлах «stddef.h» и «wchar.h». Разрядность «широкого символа» зависит от реализации компилятора.

Тип ptrdiff_t

Тип ptrdiff_t создан для хранения разности между двумя указателями. Разрядность типа ptrdiff_t зависит от платформы и реализации компилятора.

Ссылки

Примечания

  1. Макрос offsetof() (англ.). cppreference.com
  2. offsetof reference. MSDN. Проверено 19 сентября 2010.
  3. Описание макроса offsetof(). Документация gcc. gnu.org. Free Software Foundation. Проверено 19 сентября 2010.
  4. What is the purpose and return type of the __builtin_offsetof operator?. Проверено 20 октября 2012.
  5. Greg Kroah-Hartman (англ.). Макрос container_of(). Журнал «Linux Journal» (Июнь 2003). Проверено 19 сентября 2010.
  6. Оператор typeof(). Документация gcc. gnu.org
  7. Тип size_t. cppreference.com

Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".

Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.

Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .




Текст в блоке "Читать" взят с сайта "Википедия" и доступен по лицензии Creative Commons Attribution-ShareAlike; в отдельных случаях могут действовать дополнительные условия.

Другой контент может иметь иную лицензию. Перед использованием материалов сайта WikiSort.ru внимательно изучите правила лицензирования конкретных элементов наполнения сайта.

2019-2024
WikiSort.ru - проект по пересортировке и дополнению контента Википедии