我正在将32位ARM代码移植到64位x86,并遇到以下错误:
format '%lli' expects argument of type 'long long int',
but argument 3 has type 'int64_t'我找到了很多关于在这种情况下使用PRIi64的信息,但没有关于“为什么我不能使用lli?”的信息。
#include <stdio.h>
#include <inttypes.h>
int main() {
int64_t hugo = 993;
long long int fred = 994;
printf("%s -> %" PRIi64 " lli -> %lli\n", PRIi64, hugo, fred);
return 0;
}上面的代码编译没有错误,并打印li -> 993 lli -> 994。那么,如果int64_t (8字节)和long long int (8字节)具有相同的大小,为什么我还需要li和lli呢?
我找到了一个帖子,上面写着,这是a portability issue warning。那么关闭这个警告就可以了吗?(我找到的唯一标志是-Wno-format,它禁用了相当多的检查...)
发布于 2016-07-06 03:59:35
即使在大小和表示匹配的平台上,从int*到short*或long*的转换也需要强制转换,但在对两个(或更多)类型使用相同表示的实现上,可以使用指向这两个类型的指针来访问另一个类型的数据。对这种用法的支持并不被认为是C语言的“扩展”,而更像是“嗯,它还能做什么呢?”这似乎如此明显,以至于不需要文档(*)
然而,gcc的作者假设,不会使用指向非字符整数类型的指针来访问任何其他非字符整数类型的对象--即使是那些大小和表示形式相同的对象。由于printf将使用long long int*读取%lld的参数,使用long*读取%ld的参数,使用int*读取%d的参数,因此在将int64_t类型定义为<代码>d15以外的实现上,任何试图使用%lld处理int64_t类型的参数的尝试都会被视为未定义的行为,即使其大小和表示将如预期的那样。
(*)虽然C89要求所有“扩展”都被记录在案,但列出常见扩展的附件并没有列出它。由于标准的作者不可能没有意识到许多--如果不是大多数--编译器具有两个或更多共享相同大小和表示的整数类型,并且允许指向这些类型的指针可互换地使用,因此唯一合理的结论是,他们不认为这种行为是需要文档的“扩展”。
https://stackoverflow.com/questions/38180409
复制相似问题