Почему новые строки параметров формата printf () не были приняты как часть C99?
исследуя, как сделать кросс-платформенный printf()
форматировать строки в C (то есть с учетом количества битов я ожидаю, что каждый целочисленный аргумент будет printf()
должно быть) я наткнулся этот раздел статьи Википедии на printf()
. В статье рассматриваются нестандартные параметры, которые могут быть переданы в printf()
форматировать строки, такие как (что кажется расширением для Microsoft):
printf("%I32dn", my32bitInt);
далее говорится, что:
ISO C99 включает в себя inttypes.жатка Н файл, содержащий несколько макросов для использования в независимой от платформы printf кодирование.
... а затем перечисляет набор макросов, которые можно найти в указанной в заголовке. Глядя на заголовочный файл, чтобы использовать их, мне пришлось бы написать:
printf("%"PRId32"n", my32bitInt);
мой вопрос: я что-то пропустила? Это действительно стандартный способ C99 сделать это? Если так, то почему? (Хотя я не удивлен, что никогда не видел код, который использует формат струны сюда, так как это кажется таким громоздким...)
5 ответов
обоснование C, по-видимому, подразумевает, что
был получен из одноименного заголовка, найденного в нескольких существующих 64-разрядных системах.
но остальная часть текста не пишет об этих макросах, и я не помню, чтобы они существовали в то время.
то, что следует, - это просто спекуляция, но образованная опытом того, как стандартизация работа комитета.
одним из преимуществ макросов C99 над стандартизацией дополнительного спецификатора формата для printf (обратите внимание, что C99 также добавил Некоторые) является предоставление <inttypes.h>
и <stdint.h>
когда у вас уже есть реализация, поддерживающая необходимые функции определенным образом, это просто запись двух файлов с адекватными typedef и макросами. Это снижает затраты на приведение существующей реализации в соответствие, снижает риск нарушения существующих программ, которые использовали существующие особенности реализации (стандартный способ не вмешивается) и облегчают перенос соответствующих программ на реализацию, у которых нет этих заголовков (они могут быть предоставлены программой). Кроме того, если конкретные способы реализации уже варьировались в то время, это не благоприятствует одной реализации по сравнению с другой.
правильно, это как стандарт C99 говорит, что вы должны использовать их. Если вы хотите по-настоящему portablt код, на 100% соответствующие стандартам к письму, вы всегда должны напечатать int
используя "%d"
и int32_t
используя "%"PRId32
.
большинство людей не смущает, поскольку есть очень мало случаев, когда отказ от этого вещества. Если вы не переносите свой код на Win16 или DOS, вы можете предположить, что sizeof(int32_t) <= sizeof(int)
, так что это безвредно случайно printf int32_t
как int
. Кроме того,long long
в значительной степени универсально 64 бита (хотя это не гарантируется), поэтому печать int64_t
как long long
(например,%llx
спецификатор) также безопасен.
типы int_fast32_t
, int_least32_t
, et al почти никогда не используются, поэтому вы можете себе представить, что их соответствующие спецификаторы формата используются еще реже.
вы всегда можете бросить вверх и использовать %jd
что это intmax_t
формат описателя.
printf("%jd\n", (intmax_t)(-2));
Я intmax_t
чтобы показать, что любой intXX_t
можно использовать, но просто бросать в long
на int32_t
case, затем используйте %ld
.
Я могу только гадать, почему. Мне нравится ответ выше AProgrammer, но есть один аспект упускается из виду: что вы собираетесь добавить в printf в качестве модификатора формата? уже есть два разных способа использования чисел в строке формата printf (ширина и точность). Добавление третьего вида числа, чтобы сказать, сколько битов точности в аргументе, было бы здорово, но куда вы собираетесь поместить его, не смущая людей? К сожалению, один из недостатков C е, что не был разработан, чтобы быть расширяемым.
макросы ужасны, но когда вам нужно написать код, который переносим на 32-битных и 64-битных платформах, они являются находкой. Определенно спас мою шкуру.
Я думаю, что ответ на ваш вопрос почему либо
- никто не мог придумать лучшего способа сделать это, или
- комитет по стандартам не мог договориться ни о чем, что они чувствовали, было явно лучше.
другая возможность: обратная совместимость. Если вы добавите больше спецификаторов формата в printf
или дополнительные параметры, возможно, что спецификатор в некотором коде до C99 будет иметь строку формата, интерпретируемую по-разному.
С изменением C99 вы не изменяете функциональность printf
.