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

StackOverflow https://stackoverflow.com/questions/1183679

Вопрос

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

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

Далее в нем говорится , что:

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

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

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

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

Это было полезно?

Решение

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

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

но в остальной части текста не говорится об этих макросах, и я не помню, чтобы они применялись в то время.

То, что следует далее, является всего лишь предположением, но основанным на опыте работы комитетов по стандартизации.

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

Другие советы

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

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top