我想知道如何在clang中使用_ExtInt
而不使用转换来打印输出,类似于这样:
#include <stdio.h>
int main() {
_ExtInt(13) foo = 100;
printf("%???", foo);
}
使用强制类型转换,代码将如下所示(这不是我想要的):
#include <stdio.h>
int main() {
_ExtInt(32) foo = 100;
printf("%d", (int) foo);
}
_ExtInt
类型是 Clang (LLVM) 的新特性,详见 2020-04-21 发布的 The New Clang _ExtInt
Feature Provides Exact Bitwidth Integer Types。如果 _ExtInt(32)
是一个 32 位带符号整数类型并且 int
也是一个 32 位带符号整数类型,则可以在两次调用 printf()
时使用 %d
而不需要转换。在格式之后的参数会遵循整数提升规则,因此我预计在传递给 printf()
时,_ExtInt(13)
和 _ExtInt(32)
都将被转换为 int
,因此正确的转换说明符是 %d
。_ExtInt(64)
,在任何机器上都可以使用 %lld
(或者在 64 位机器上使用 %ld
)。如果您使用超过这个范围的类型,那么您需要一个实现了如何处理 _ExtInt
类型的 printf()
,并且这可能需要在格式中使用标记来指定长度。例如,假设它支持一个带符号的 _ExtInt(700)
,那么它可能会支持 %<700>d
。通过组成一个long
类型的产品使用宽类型。 int
可能是16位的。 long
至少为32位。 long long
至少为64位。
_ExtInt(13) foo1 = 100;
printf("%d\n", 1 * foo);
// or
printf("%d\n", 0 + foo);
_ExtInt(32) foo2 = 100;
printf("%ld\n", 1L * foo);
// or
printf("%ld\n", 0L + foo);
printf()
实现来处理_ExtInt(700)
。你需要查看提供的库支持的内容,可能需要特殊的文档说明。他们可能在等待WG14(C标准委员会)提供指导。 - Jonathan Leffler
+
这样的运算符两侧必须具有相同的大小,所以你不能在没有显式转换的情况下添加_ExtInt(8)
和_ExtInt(12)
。"调用约定"的注释和周围的文本暗示着_ExtInt(13)
将被扩展为适当的较大大小(可能是16位或32位 —— 我强烈怀疑对于传统芯片来说是32位,而不是它所针对的FGPA芯片)。这两个参考资料都有很多未提及的内容。 - Jonathan Leffler_ExtInt(21)
(例如用于Unicode字符),那么你可以将_ExtInt(21)
作为参数传递给该函数,而不能传递其他类型。_ExtInt(16)
不会被隐式提升为_ExtInt(21)
。但是printf()
和可变参数函数要求比int
更短的类型必须转换为int
。要么你无法在没有强制类型转换的情况下将_ExtInt(21)
传递给printf()
,要么它会被提升为int
(假设是32位的int
)。我认为“现有的调用约定”注释意味着你可以这样做。但我还没有真正尝试过。 - Jonathan Leffler