2017-01-11 42 views
1

我正在使用getrlimit()函数来获取我系统上的最大堆栈大小。该功能将两个rlim_t字段中的当前限制和最大限制存储在struct中。我想打印这些值。打印rlim_t类型值的正确方法是什么?

我发现this link这表明rlim_tunsigned整数类型,所以就用PRIuMAX宏用于转换说明,该值铸造(uintmax_t)。我注意到,我可以省略演员阵容而不会产生任何警告;这里真的有必要吗?

在挖掘了几个头文件之后,我发现rlim_t对我的系统来说是对于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

我相信这是一个unsigned long。

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

好的,你需要从该代码中删除'PRIuMAX'宏,正如我在我的问题中所述:“我发现'rlim_t'是我的系统上'unsigned long'的'typedef'。问题是,我可以假设它是_always_'unsigned long',还是使用可能的最宽可能的'unsigned'整数类型更好? –

相关问题