Типы целых чисел C
Вот несколько рекомендаций по использованию целочисленных типов в исходном коде Emacs C. Эти рекомендации иногда дают противоречивые советы; рекомендуется проявлять здравый смысл.
- Избегайте произвольных ограничений. Например, избегайте
int len = strlen (s);, если длинаsне требуется по другим причинам для размещения в диапазонеint. - Не предполагайте, что арифметика со знаковыми целыми числами переполняется при переполнении. Это больше не относится к целевым платформам Emacs: переполнение знакового целого числа в действительности имеет неопределенное поведение и может привести к выводу ядра или даже к нелогичному поведению кода раньше или позже. Переполнение беззнакового целого числа надежно переполняется по модулю степени двойки.
- Предпочитайте знакомые типы беззнаковым, так как код становится запутанным, когда знакомые и беззнаковые типы сочетаются. Многие другие рекомендации предполагают, что типы знакомые; в более редких случаях, когда необходимы беззнаковые типы, могут применяться аналогичные рекомендации для беззнаковых аналогов (например,
size_tвместоptrdiff_t, илиuintptr_tвместоintptr_t). - Предпочитайте
intдля кодов символов Emacs в диапазоне 0 .. 0x3FFFFF. В более общем смысле, предпочитайтеintдля целых чисел, известные в диапазонеint, например, количества столбцов экрана. - Предпочитайте
ptrdiff_tдля размеров, т. е. для целых чисел, ограниченных максимальным размером любого отдельного объекта C или максимальным количеством элементов в любом массиве C. Это часть общей предпочтения Emacs знаковым типам. Использованиеptrdiff_tограничивает объекты доPTRDIFF_MAXбайтов, но более крупные объекты все равно вызовут проблемы, поскольку они нарушат вычитание указателей, поэтому это не накладывает произвольного ограничения. - Избегайте
ssize_tза исключением случаев связи с низкоуровневыми API, имеющими ограничения, связанные сssize_t. Хотя на типичных платформах он эквивалентенptrdiff_t,ssize_tиногда уже, поэтому его использование для расчетов размера может привести к переполнению. Кроме того,ptrdiff_tболее распространен и лучше стандартизован, имеет стандартные форматыprintfи является основой для проверки переполнения размера внутри Emacs. При использованииssize_t, обратите внимание, что POSIX требует поддержки только значений в диапазоне -1 ..SSIZE_MAX. - Обычно предпочтительнее
intptr_tдля внутренних представлений указателей или целых чисел, ограниченных только количеством объектов, которые могут существовать в любой момент времени, или общим количеством байтов, которые могут быть выделены. Однако предпочитайтеuintptr_tдля представления арифметики указателей, которая может пересекать страницы. Например, на машине с 32-разрядным адресным пространством массив может пересечь границу 0x7fffffff/0x80000000, что приведет к переполнению целого числа при добавлении 1 к(intptr_t) 0x7fffffff. - Предпочитайте определенный Emacs тип
EMACS_INTдля представления значений, преобразованных в или из fixnum Emacs Lisp, так как арифметика fixnum основана наEMACS_INT. - При представлении системного значения (например, размера файла или количества секунд с момента эпохи) предпочтительнее соответствующий системный тип (например,
off_t,time_t). Не предполагайте, что системный тип является знаковым, если эта предположение не известно, что безопасно. Например, хотяoff_tвсегда знаком,time_tможет и не быть. - Предпочитайте
intmax_tдля представления значений, которые могут быть любым знаковым целым числом. Функция семействаprintfможет вывести такое значение с помощью формата, такого как"%"PRIdMAX. - Предпочитайте
bool,falseиtrueдля булевых значений. Использованиеboolможет сделать программы более читаемыми и немного быстрее, чем использованиеint. Хотя использованиеint,0и1также допустимо, этот более старый стиль постепенно отменяется. При использованииbool, учитывайте ограничения реализации заменыbool, как документировано в файле исходного кода lib/stdbool.in.h. В частности, битовые поля булевых значений должны быть типаbool_bf, а неbool, чтобы они работали правильно даже при компиляции Objective C с стандартным GCC. - В битовых полях предпочтительнее
unsigned intилиsigned intвместоint, так какintменее портативен: он может быть знаковым и может не быть. Однобитовые битовые поля должны бытьunsigned intилиbool_bf, чтобы их значения были 0 или 1.
Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/C-Integer-Types.html