Как можно напечатать переменную size_t с помощью семейства printf? - PullRequest
339 голосов
/ 26 марта 2010

У меня есть переменная типа size_t, и я хочу напечатать ее, используя printf(). Какой спецификатор формата я использую для его печати?

В 32-битной машине %u кажется правильным. Я скомпилировал с g++ -g -W -Wall -Werror -ansi -pedantic, и не было никакого предупреждения. Но когда я компилирую этот код на 64-битной машине, он выдает предупреждение.

size_t x = <something>;
printf( "size = %u\n", x );

warning: format '%u' expects type 'unsigned int', 
    but argument 2 has type 'long unsigned int'

Предупреждение исчезнет, ​​как и ожидалось, если я изменю его на %lu.

Вопрос в том, как мне написать код, чтобы он бесплатно компилировал предупреждения на 32- и 64-разрядных компьютерах?

Редактировать: В качестве обходного пути, я думаю, один из ответов мог бы состоять в том, чтобы "привести" переменную в целое число, которое достаточно велико, скажем, unsigned long, и напечатать, используя %lu. Это будет работать в обоих случаях. Я смотрю, есть ли другая идея.

Ответы [ 12 ]

0 голосов
/ 26 марта 2010

C99 определяет "% zd" и т. Д. Для этого. (спасибо комментаторам) В C ++ для этого нет переносимого спецификатора формата - вы могли бы использовать %p, что в этих двух сценариях является woulkd словом, но также не является переносимым выбором и дает значение в шестнадцатеричном формате.

В качестве альтернативы используйте некоторую потоковую передачу (например, stringstream) или безопасную замену printf, например Boost Format . Я понимаю, что этот совет имеет ограниченное использование (и требует C ++). (Мы использовали подобный подход, приспособленный для наших нужд при реализации поддержки юникода.)

Фундаментальная проблема для C состоит в том, что printf, использующий многоточие, небезопасен по своей конструкции - он должен определить размер дополнительного аргумента из известных аргументов, поэтому он не может быть исправлен для поддержки «что бы вы ни получили». Так что, если ваш компилятор не реализует некоторые проприетарные расширения, вам не повезло.

0 голосов
/ 26 марта 2010

Будет ли оно предупреждать вас, если вы передадите 32-разрядное целое число без знака в формат% lu? Это должно быть хорошо, поскольку преобразование четко определено и не теряет никакой информации.

Я слышал, что некоторые платформы определяют макросы в <inttypes.h>, которые вы можете вставить в строковый литерал формата, но я не вижу этого заголовка в моем компиляторе Windows C ++, что подразумевает, что он не может быть кроссплатформенным. 1004 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...