Добро пожаловать в рубрику «Дары муравьям магия» — место‚ где рунические знаки Си превращаются в понятные инструменты. Сегодня мы рассмотрим одну из наиболее запутанных пар спецификаторов форматирования: %zu и %lu. Если вы когда-нибудь видели на экране странное слово «zu» вместо ожидаемого числа‚ эта статья для вас.
Что такое size_t и зачем нужен %zu?
Тип size_t — это беззнаковое целочисленное «что-то»‚ которое используется во всех стандартных функциях библиотеки Си для обозначения размеров и количества байт (например‚ результат sizeof‚ strlen‚ malloc). На 64-битных системах это обычно unsigned long long‚ на 32-битных — unsigned long или даже unsigned int.
Формат %zu появился в стандарте C99 и означает:
- z — длина для типа
size_t; - u — беззнаковый десятичный вывод.
Запись гарантирует‚ что программа компилируется и корректно работает на любой платформе‚ вне зависимости от конкретного размера size_t.
А можно просто %lu?
- Не портативно: на x64 Windows
size_t—unsigned long long‚ откуда при%luможно получить-1или неверное число. - Требует замечаний компилятора: GCC и Clang с ключом
-Wall -Wextraвыводят предупреждение format specifies type ‘unsigned long’ but the argument has type ‘size_t’. - future-proof: Стандарт может поменять размер
size_t‚ и ваша программа поломается.
Подводные камни Microsoft Visual Studio
Старые версии MSVC до VS2013 запросто игнорировали %zu‚ поэтому на экране вы видели буквально символы zu.
Хронология поддержки:
| Компилятор | Мин. версия | Пояснение |
|---|---|---|
| Microsoft Visual Studio | VS2015 (≥ _MSC_VER 1900) | Полная поддержка %zu |
| MSVC < 1900 | 2010-2013 | Частичная/отсутствует; можно использовать %Iu |
| GCC / Clang (libstdc) | C99+ | Всегда поддерживается |
Как безопасно выводить size_t в устаревшем компиляторе
До VS2015 «муравьи» рекомендуют:
- Microsoft-only:
printf("%Iu— здесь
"‚ value);Iозначаетsize_tв MSVC. - Кроссплатформенно:
printf("%llu "‚ (unsigned long long)value);такой каст безопасен‚ но требует явного преобразования.
- C++ (альтернатива):
std::cout << value;— перегрузка для
size_tкорректна во всем стандарте С++11+.
Мини-чек-лист для разработчика
- Если компилируете в GCC/Clang — смело используйте
%zu. - MSVC 2015 и выше:
%zu— ваш выбор. - MSVC раньше 2015: используйте
%Iuили скажите заказчику обновиться. - Если пишите кроссплатформенную библиотеку — добавьте макро-обёртку:
#ifdef _MSC_VER #else #endif printf("%" PRI_SIZET‚ my_size);
Форматный спецификатор %zu — именно то‚ что вы должны использовать для переменных типа size_t‚ начиная с C99. На современных компиляторах проблем нет‚ а старые можно обмануть макросом или явным приведением. Главное — не игнорировать предупреждения компилятора: они появляются не зря‚ даже если ваш компьютер ведёт себя как муравьиная куча.
Полезные контакты и серверы поддержки
- Электронная почта редакции:
📧 codespells@mu2race.net - Error-catch GitHub-бот для MSVC:
https://github.com/microsoft/vcpkg - Ru.StackOverflow:
🔍 Тег visual-c++ на ru.SO - Телеграм-чат «С++/Си 64-бит»:
Приглашение в чат – быстрый ответ опытных муравьёв.