printf ("% u \ n", 4294967296) выдает 0 с предупреждением на сервере Ubuntu 11.10 для i386 - PullRequest
0 голосов
/ 25 января 2012

На сервере Ubuntu 11.10 для i386 sizeof(int) равно 4, поэтому я думаю, 4294967296 - это максимальное число для типа int, не так ли? Но printf("%u\n",4294967296) выводит 0 с предупреждением:

предупреждение: формат "% u" ожидает аргумент типа "unsigned int", но аргумент 2 имеет тип 'long long unsigned int' [-Wformat]

Есть предложения?

Версия gcc: (Ubuntu / Linaro 4.6.1-9ubuntu3) 4.6.1

Ответы [ 4 ]

8 голосов
/ 25 января 2012

4294967296 - это ровно 2 ^ 32, что на 1 превышает максимум, поддерживаемый unsigned int (при условии 32-разрядного).Таким образом, C обрабатывает этот целочисленный литерал так, как если бы он имел следующий целочисленный тип, который может представлять его (long long int).(Я не уверен, почему предупреждение жалуется, что оно long long unsigned int).

Поэтому вы вызвали неопределенное поведение, предоставив несоответствие между вашим спецификатором формата и типами аргументов (на практике вы простопросмотр по модулю).

Измените спецификатор формата на "%llu\n".

3 голосов
/ 25 января 2012

Вы можете использовать константы в limit.h , чтобы определить максимально возможные и минимально возможные значения для различных типов для вашей реализации. Попробуйте

printf("%u\n", UINT_MAX);

и вы обнаружите, что вывод:

4294967295

Но вы просите printf() напечатать 4294967296, что превышает максимально возможное целое число без знака для вашей реализации.

Значение UINT_MAX имеет смысл, поскольку вы сказали нам, что sizeof (int) равно 4. Максимально возможное 4-байтовое целое или 32-битное целое число равно 111111111 111111111 111111111 111111111 при выражении в двоичном формате или FFFFFFFF при выражении в шестнадцатеричном виде или 4294967295 при выражении в десятичном формате.

У вас есть два способа исправить этот код. Простой способ:

printf("%llu\n", 4294967296ull);

Более портативный способ исправить это с помощью стандарта ISO C99:

printf("%" PRIu64 "\n", (uint64_t) 4294967296);

Для последнего вам нужно #include <inttypes.h>.

1 голос
/ 25 января 2012

Тип нефиксированного целочисленного литерала, такого как 4294967296, зависит от значения литерала и диапазонов предопределенных типов для реализации.

Тип десятичной константы является первым из:

  • int
  • long int
  • long long int

(восьмеричные и шестнадцатеричные литералы могут быть беззнакового типа;подробности см. в разделе 6.4.4.1 стандарта C99 .)

, в котором его значение может быть точно представлено.Язык требует, чтобы int составлял не менее 16 бит, long int - не менее 32 бит, а long long int - не менее 64 бит, но каждый может быть шире.

В вашей системе (Ubuntu,32 бита, как у меня), int и long int - 32 бита, а long long int - 64 бита, поэтому 4294967296 имеет тип long long int.(Сообщение, которое вы нам показали, указывает на то, что это long long unsigned int, что кажется неправильным; вы уверены, что это сообщение, которое вы получили для этого конкретного кода?)

Поведение вызова printf с аргументомтипа, несовместимого с форматом, не определено.Вы, вероятно, получили 9 в качестве вывода, потому что переданное значение было 0x0000000100000000, а printf случайно использовал младшие 32 бита 64-битного значения.Возможно другое поведение.

Вы спрашиваете «Любое предложение», но из вашего вопроса не ясно, что вы хотите сделать.Способ получения результата, который вы, вероятно, ожидали:

puts("4294967296");

, но я уверен, что это не тот ответ, который вы ищете.

Обычно, когда вы печатаете число сprintf, аргумент будет переменной, а не литералом, а тип будет определяться объявленным типом переменной.Или это может быть более сложное выражение, в этом случае тип определяется типами операндов;если они разных типов, есть умеренно сложный набор правил, определяющих конечный результат.Просто убедитесь, что используемый вами формат соответствует (повышенному) типу аргумента.

Если у вас есть более конкретный вопрос, мы будем рады дать более конкретный ответ.

0 голосов
/ 25 января 2012

Если вы хотите сделать это в портативном режиме, посмотрите на здесь .

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