printf с sizeof на 32 против 64 платформ: как мне обрабатывать код формата независимо от платформы?

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

  •  05-07-2019
  •  | 
  •  

Вопрос

У меня есть код, который печатает объем памяти, используемый программой. Строка похожа на это:

printf("The about of RAM used is %u", anIntVariable*sizeof(double) );

где anIntVariable - это переменная типа int для числа элементов двойного массива. В любом случае, на 32-битных системах у меня никогда не возникало проблем, но на 64-битных системах я получаю предупреждение компилятора об использовании "% u " для целого числа без знака. Использование "% lu " поскольку код формата устраняет проблему в 64-битной среде, но компилятор выдает жалобу в 32-битной системе, поскольку тип возвращается к unsigned int. Я обнаружил, что действительно sizeof (double) возвращает другое значение в 32-х и 64-х битных системах. Я нашел несколько руководств для веб-страниц, чтобы преобразовать код из 32-битного в 64-битный. Но я бы предпочел иметь код, который работает на обоих, а не просто конвертировать туда и обратно.

Как мне написать эту строку независимо от платформы? Я знаю много способов, которыми я мог бы сделать это, используя директивы препроцессора, но это похоже на хак. Конечно, есть элегантный способ, который я не понимаю.

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

Решение

Переносимые идентификаторы printf предоставляются во включаемом файле inttypes.h .

Этот включаемый файл имеет много переносимых идентификаторов для вашей конкретной среды выполнения. Для вашего примера вы хотите, чтобы PRIuPTR, что означает PR intf I средство для удаления u , было подписано размером до размера указателя ".

Ваш пример будет таким:

printf("The amount of RAM used is %" PRIuPTR, anIntVariable*sizeof(double) );

Результаты на 64-битной Linux с GCC 4.3 ( int anIntVariable = 1 ):

$ gcc test.c -m32 -o test && ./test
The amount of RAM used is 8
$ gcc test.c -o test && ./test
The amount of RAM used is 8

Для полноты картины также есть идентификаторы для scanf, префиксы которых - SCN.

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

Возвращаемое значение sizeof - size_t. Если вы используете компилятор, совместимый с C99, похоже, что для этого вы можете использовать % zd % zu .

D'oh: % zu (без знака), конечно. Спасибо, только.

Прежде всего, вы должны соответствовать значению "% " спецификатор с фактическим типом данных, который вы хотите напечатать. sizeof возвращает тип данных size_t , и точно так же, как вы не должны пытаться печатать с плавающей точкой, используя "% d " спецификатор, вы не должны пытаться напечатать size_t с "% u " или "% d" или что-нибудь, что на самом деле не означает size_t.

Другие ответы дали несколько хороших способов справиться с этим с помощью новых компиляторов ("% z " и PRIu32), но способ, которым мы привыкли это делать, заключался в простом приведении size_t к unsigned long, а затем распечатке его с использованием & Quot;% лу & Quot;

printf("The amount of RAM used is %lu", (unsigned long)(anIntVariable*sizeof(double)) );

Это не будет работать в системах, где size_t шире, чем long, но я не знаю ни одной из таких систем, и я даже не уверен, позволяет ли это стандарт.

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