Подтвердить что ты не робот

Почему в качестве части C99 не были введены новые параметры формата printf() для новых (с шириной)?

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

printf("%I32d\n", my32bitInt);

Далее указывается, что:

ISO C99 включает заголовок inttypes.h файл, который включает в себя несколько макросов для использования в платформенно-независимой печати кодирование.

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

 printf("%"PRId32"\n", my32bitInt);

Мой вопрос: я что-то упустил? Действительно ли это стандартный способ C99? Если да, то почему? (Хотя я не удивлен, что я никогда не видел код, который использует строки формата таким образом, поскольку он кажется таким громоздким...)

4b9b3361

Ответ 1

Обоснование C подразумевает, что < inttypes.h > стандартизирует существующую практику:

< inttypes.h > был получен из заголовка с тем же именем, который был найден в нескольких существующих 64-битных системах.

но оставшаяся часть текста не пишет об этих макросах, и я не помню, что они существовали в то время.

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

Одно из преимуществ макросов C99 над стандартизацией дополнительного спецификатора формата для printf (обратите внимание, что C99 также добавил некоторые) заключается в том, что предоставление <inttypes.h> и <stdint.h>, когда у вас уже есть реализация, поддерживающая требуемые функции в конкретном способе реализации просто записывает два файла с адекватным typedef и макросами. Это снижает затраты на обеспечение соответствия существующей реализации, снижает риск нарушения существующих программ, которые используют существующие функции специфики реализации (стандартный способ не мешает) и облегчают перенос согласованных программ на реализацию, у которых нет этих (они могут быть предоставлены программой). Кроме того, если конкретные пути реализации уже изменились в то время, это не способствует реализации одной реализации над другой.

Ответ 2

Правильно, так говорит стандарт C99, который вы должны использовать. Если вам нужен действительно код portablt, который соответствует стандарту 100%, соответствующему букве, вы всегда должны печатать int с помощью "%d" и int32_t с помощью "%"PRId32.

Большинство людей не будут беспокоиться, так как очень мало случаев, когда неспособность сделать это имеет значение. Если вы не портируете свой код на Win16 или DOS, вы можете предположить, что sizeof(int32_t) <= sizeof(int), поэтому безвредно случайно напечатать a int32_t как int. Аналогично, a long long имеет довольно много 64 бит (хотя это и не гарантировано), поэтому печать int64_t как long long (например, с помощью спецификатора %llx) также безопасна.

Типы int_fast32_t, int_least32_t и т.д. почти никогда не используются, поэтому вы можете себе представить, что их соответствующие спецификаторы формата используются еще реже.

Ответ 3

Вы всегда можете отбрасывать вверх и использовать %jd, который является спецификатором формата intmax_t.

printf("%jd\n", (intmax_t)(-2));

Я использовал intmax_t, чтобы показать, что можно использовать любой intXX_t, но простое приведение к long намного лучше для случая int32_t, затем используйте %ld.

Ответ 4

Я могу только рассуждать о том, почему. Мне нравится AProgrammer ответить выше, но там один аспект упущен: , что вы собираетесь добавить в printf в качестве модификатора формата? Есть уже два разных способа использования чисел в строке формата printf (ширина и точность). Добавление третьего типа числа, чтобы сказать, сколько бит точности в аргументе будет здорово, но где вы собираетесь его использовать, не запутывая людей? К сожалению, одним из недостатков C является то, что printf не был предназначен для расширения.

Макросы ужасны, но когда вам приходится писать код, который переносится на 32-битные и 64-разрядные платформы, они являются находкой. Определенно спасенный мой бекон.

Я думаю, что ответ на ваш вопрос почему есть либо

  • Никто не мог придумать лучшего способа сделать это, или
  • Комитет по стандартам не мог согласиться с тем, что, по их мнению, явно лучше.

Ответ 5

Другая возможность: обратная совместимость. Если вы добавите дополнительные спецификаторы формата в printf или дополнительные параметры, возможно, что спецификатор в некотором коде pre-C99 будет иметь строку формата, интерпретированную по-разному.

При изменении C99 вы не меняете функциональность printf.