我需要一种可移植的方式来打印类型变量n的值size_t
.由于我使用ANSI C89,我不能使用z
长度修饰符.我目前的做法是将价值投射到long unsigned int
:
printf("%lu\n", (long unsigned int) n);
Run Code Online (Sandbox Code Playgroud)
只要size_t
被定义为unsigned int
或者long unsigned int
我看不出它会如何失败.演员安全吗?
Bil*_*uya 16
在C89中,size_t
被定义为无符号整数类型.与未来的标准不同,C89定义了无符号整数类型列表如下:
因此,size_t
在C89中永远不会大于unsigned long
,因此强制转换总是安全的 - 因为它不会导致任何未定义的行为,并且它总是足够大以保持整个值.
值得注意; C89标准规定: "符合标准的实现可能具有扩展(包括附加库函数),前提是它们不会改变任何严格符合程序的行为" 意味着没有扩展可以改变这种行为 - 同时仍然符合C89标准,如已经专门列出了无符号整数类型,因此无法更改.
在未来的标准中,这不是保证,虽然您不会得到未定义的行为 - 您可能会丢失unsigned long
小于的数据size_t
,这意味着您将向用户显示不正确的数据.在这种情况下,我会犹豫是否将其标记为"安全".
作为重要的补充说明; 这个答案指的是符合C89标准的编译器.您的C89编译器可能在上述方面"低于兼容",在这种情况下 - 将行为视为类似于C99或更新的行为,您将看不到未定义的行为,但如果size_t
是,则可能会遭受数据丢失大于unsigned long
.但要明确,这不符合C89标准.
除此之外,虽然我对标准(1.7合规性)的解释是,虽然它规定扩展不得改变"严格符合程序"的行为,因此不能改变size_t
必须unsigned long
在没有遵守的情况下最大的事实; 它并没有改变这种扩展确实存在的事实.例如,GNU GCC确实提供了添加的扩展unsigned long long
.在我看来,这是不合规的,但现实是你必须准备好处理这样的事情 - 同时标准说你正在做的事情是完全安全的,你必须准备好在不合规的情况下潜在的数据丢失使用编译器或扩展.
有关此主题的讨论,请参阅此处:https: //stackoverflow.com/a/39441237/955340