Используется ли правильный синтаксис %zu в строке формата printf, как показано в каком-то коде C, найденном в Википедии?

Я только что нашел этот код в Википедии.
Ссылка: http://en.wikipedia.org/wiki/Sizeof#Use

Код:

/* the following code illustrates the use of sizeof 
 * with variables and expressions (no parentheses needed),
 * and with type names (parentheses needed)
 */

char c;

printf("%zu,%zu", sizeof c, sizeof(int));

В нем говорится, что: «Для печати следует использовать префикс z, потому что фактический размер может отличаться для каждой архитектуры».

Я попробовал это на своем компиляторе, но он дает следующий результат:

zu,zu

person m4design    schedule 28.05.2010    source источник


Ответы (5)


Да, этот синтаксис правильный (по крайней мере, для C99). Похоже, ваш компилятор не настроен для обработки этого. Просто выньте z и все будет в порядке. Чтобы быть правильным, убедитесь, что ваши спецификаторы формата printf соответствуют размеру типов. Включение всех предупреждений, которые выдает ваш компилятор, вероятно, помогает в этом отношении.

Ваша цитата:

Для его печати следует использовать префикс z, поскольку фактический размер может различаться в зависимости от архитектуры.

ссылается на тот факт, что size_t (тип, возвращаемый оператором sizeof) может варьироваться от архитектуры к архитектуре. z предназначен для того, чтобы сделать ваш код более переносимым. Однако, если ваш компилятор не поддерживает его, это не сработает. Просто играйте с комбинациями %u, %lu и т. д., пока не получите осмысленный вывод.

person Carl Norum    schedule 28.05.2010
comment
Вы можете использовать %lu и явно привести значение sizeof к unsigned long - если вы знаете, что размер объекта меньше 4 ГБ, вы знаете, что он определенно будет сообщен правильно. - person caf; 29.05.2010

Модификатор длины z был добавлен в C в стандарте C99; у вас может быть компилятор, который не поддерживает C99.

Если ваш компилятор C не поддерживает это, вы, вероятно, можете рассматривать размеры как unsigned long:

printf("%lu,%lu", (unsigned long)sizeof c, (unsigned long)sizeof(int));
person nos    schedule 28.05.2010

Да, но он работает только с компиляторами, совместимыми с C99. Из википедии:

z: для целочисленных типов заставляет printf ожидать целочисленный аргумент размера size_t.

person BlueRaja - Danny Pflughoeft    schedule 28.05.2010

Вы сказали своему компилятору, что хотите, чтобы он думал мозгом C99? Вероятно, для этого есть переключатель. Например, -std=c99 для gcc.

Если ваш компилятор не поддерживает его, но вы знаете, что другие будут, вы можете сделать обходной путь в стиле PRId64 (отказ от ответственности - ПСЕВДОКОД ВПЕРЕД ..):

#ifdef __SOME_KNOWN_C99_COMPILER
#define PORTUNSIGNED "zu"
#else
#define PORTUNSIGNED "u"
#endif

printf("%-11" PORTUNSIGNED " ways to skin a cat\n");

Однако, вероятно, лучше получить компилятор, который имеет функциональную поддержку c99.

person Tim Post♦    schedule 28.05.2010
comment
Препроцессор не зло. - person Nathan Osman; 28.05.2010
comment
@ Джордж - я не говорю, что это зло, я просто говорю, что некоторые перестают его использовать и начинают с ним импровизировать, что приводит к интересным вещам, которые в конечном итоге приходится поддерживать другим людям :) - person Tim Post♦; 29.05.2010

Я сделал тест, используя gcc 4.0. Работает с -std=c99

person pcent    schedule 28.05.2010