Подтвердить что ты не робот

Кросс-платформенная печать 64-битных целых чисел с printf

В Windows это "% I64d". В Linux и Solaris это "% lld".
Если я хочу написать кросс-платформенный printfs, который печатает значения long long: что это хороший способ сделать это?

long long ll;
printf(???, ll);
4b9b3361

Ответ 1

Существует несколько подходов.

Вы можете написать свой код в соответствии с C99, а затем предоставить системные хаки, когда авторы компиляторов подведут вас. (К сожалению, это довольно распространено в C99.)

#include <stdint.h>
#include <inttypes.h>

printf("My value is %10" PRId64 "\n", some_64_bit_expression);

Если одна из ваших целевых систем пренебрегла реализацией <inttypes.h> или каким-то другим образом отвратительно отступила, поскольку некоторые из функций типа являются необязательными, вам просто нужен системный #define для PRId64 ( или что-то еще) в этой системе.

Другим подходом является выбор того, что в настоящее время всегда реализуется как 64-битное и поддерживается printf, а затем выполняется. Не идеально, но это часто происходит:

printf("My value is %10lld\n", (long long)some_64_bit_expression);

Ответ 2

MSVC поддерживает long long и ll, начиная с Visual Studio 2005.

Вы можете проверить значение _MSC_VER macro (>= 1400 за 2005 год) или просто не поддерживать старые компиляторы.

Он не предоставляет макросы C99, поэтому вам нужно будет использовать long long вместо использования PRId64.

Это не поможет, если вы используете старые библиотеки MSVC с компилятором, отличным от MSVC (я думаю, что mingw, по крайней мере, предоставляет собственную версию printf, которая поддерживает ll)

Ответ 3

Нет на linux и solaris, это только случайно, что это lld для 64-битного типа. C99 предписывает простые (но уродливые) макросы, чтобы сделать эти вещи переносимыми PRId64. Поскольку некоторые компиляторы Windows не соответствуют стандарту, вам может быть не повезло, там, к сожалению.

Изменить: В вашем примере вы используете другое, чем 64-битное целое число, а именно long long. Это может быть 128 на некоторых архитектурах. Здесь C99 имеет typedef, который гарантирует минимальную или точную ширину типа (если они реализованы на платформе). Эти типы найдены с заголовком inttypes.h, а именно int64_t для 64-разрядного типа с фиксированной шириной, представленного в двух дополнениях. Может быть, или, может быть, ваш компилятор Windows не имеет этого.

Ответ 4

В качестве альтернативы вы можете использовать такой код:

uint64_t currentTimeMs = ...;

printf("currentTimeMs = 0x%08x%08x\n",
            (uint32_t)(currentTimeMs >> 32),
            (uint32_t)(currentTimeMs & 0xFFFFFFFF)
    );

Или, может быть:

printf("currentTimeMs = %u%09u\n",
            (uint32_t)(currentTimeMs / 1000000000),
            (uint32_t)(currentTimeMs % 1000000000)
    );