2017-01-11 5 views
1

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

this link я нашел, что позволяет предположить, что rlim_t является типом unsigned целого числа, так что я использовал PRIuMAX макрокоманды для спецификатора преобразования, отбрасывая значения в (uintmax_t). Я заметил, что могу опустить бросок, не создавая никаких предупреждений; действительно ли настоящая личность?

После обработки нескольких файлов заголовков я обнаружил, что rlim_t является typedef для unsigned long в моей системе. Поэтому я мог бы также использовать спецификатор преобразования %lu и покончить с литой.

Я не думаю, что могу предположить, что rlim_t всегда unsigned long, поэтому лучше использовать первый способ улучшения переносимости. Я нашел this answer, что предполагает, что %llu не всегда может быть действительным спецификатором преобразования для rlim_t и защищает листинг до long long. Каков наилучший способ печати значения типа rlim_t?

Вот краткая иллюстративная программа:

#include <stdio.h> 
#include <stdlib.h> 
#include <inttypes.h> 
#include <sys/resource.h> 

int main(void) 
{ 
    struct rlimit stacklim; 
    rlim_t cur_bytes, max_bytes; 

    if (getrlimit(RLIMIT_STACK, &stacklim) == 0) { 
     cur_bytes = stacklim.rlim_cur; 
     max_bytes = stacklim.rlim_max; 
    } else { 
     perror("Error in getrlimit()"); 
     exit(EXIT_FAILURE); 
    } 

    puts("Maximum Stack Size"); 
    printf("Soft limit: %" PRIuMAX " bytes\n", (uintmax_t)cur_bytes); 
    printf("Hard limit: %" PRIuMAX " bytes\n", (uintmax_t)max_bytes); 

    return 0; 
} 
+2

Вашего существующее решение в порядке, и вы должны используйте приведение в случае изменения типа в другой версии системных заголовков. –

+1

Согласитесь с @MM - если вы используете 'PRIuMAX' и не уверены, что' cur_bytes' уже является типом, совместимым с 'uintmax_t' в соответствии с правилами рассылки по умолчанию, которые применяются к форматированным аргументам' printf() ', тогда литье необходимо для обеспечения безопасности на разных платформах. Даже если вы уйдете с ним на свой текущий компьютер, он может не работать на других платформах - не рискуйте, когда стоимость будет незначительной. –

ответ

1

Как указано в комментариях к исходному вопросу, литье необходимо, чтобы убедиться, что тип соответствует спецификации преобразования. Заголовки системы могут не определять тип rlim_t как uintmax_t, но так как rlim_t является целым числом unsigned, то отливка до uintmax_t является безопасной.

выше решение, используя PRIuMAX макрос хорошо, но так как C99 существует также модификатор j типа, используемая для печати значений типа intmax_t и uintmax_t:

printf("Soft limit: %ju bytes\n", (uintmax_t)cur_bytes); 
printf("Hard limit: %ju bytes\n", (uintmax_t)max_bytes); 
-2

Я считаю, что это беззнаковое долго.

printf("Soft limit: %lu" PRIuMAX " bytes\n", cur_bytes); 
printf("Hard limit: %lu" PRIuMAX " bytes\n", max_bytes); 
+0

Ну, вам нужно удалить макросы 'PRIuMAX' из этого кода, и, как я сказал в своем вопросе:« Я обнаружил, что 'rlim_t' является' typedef' для 'unsigned long' в моей системе." Вопрос в том, могу ли я предположить, что это _always_ 'unsigned long', или лучше использовать максимально возможный тип целых чисел без знака? –

Смежные вопросы