[英]C99: Why does %lli not match int64_t on 64bit machines?
I'm porting 32bit ARM code to 64bit x86 and hit the following error: 我将32位ARM代码移植到64位x86并遇到以下错误:
format '%lli' expects argument of type 'long long int',
but argument 3 has type 'int64_t'
I found a lot info about using PRIi64
in this case, but nothing about "why I cannot use lli
?". 在这种情况下,我发现了很多有关使用
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;
}
The code above compiles without error and prints li -> 993 lli -> 994
. 上面的代码编译无误,并输出
li -> 993 lli -> 994
。 So why do I need li
for int64_t (8 bytes) and lli
for long long int (8 bytes) if both have the same size? 那么,为什么我需要
li
为的int64_t(8个字节)和lli
长期长整型(8个字节),如果两者都具有相同的大小?
I found one post which says, that it's a portability issue warning
. 我发现有一篇文章说,这是
a portability issue warning
。 So it is save to turn off this warning? 因此,保存此警告是否保存? (The only flag I found is
-Wno-format
which disable quite a lot checks...) (我发现的唯一标志是
-Wno-format
,它禁用了很多检查...)
When the Standard was written, many implementations had two or more integer types with the same size and representation; 编写标准时,许多实现都具有两个或多个具有相同大小和表示形式的整数类型。 most typically,
int
would have the same size and representation as either short
or long
. 最典型的是,
int
的大小和表示形式与short
或long
。
Even on platforms where the sizes and representations would match, conversion from int*
to a short*
or long*
requires a cast, but on implementations which used the same representation for two (or more) types, a pointer to either could be used to access data of the other. 即使在大小和表示形式都匹配的平台上,从
int*
到short*
或long*
需要强制转换,但是在对两个(或更多)类型使用相同表示形式的实现中,可以使用指向其中任何一个的指针访问对方的数据。 Support for such usage was not considered an "extension" of C, but more of a "well duh, what else would it do?" 对这种用法的支持不被认为是C的“扩展”,而是更多的“嗯,它还能做什么?” that seemed so obvious as to not require documentation(*)
似乎很明显,不需要文档(*)
The authors of gcc, however, assume that no pointer to a non-character integer type will be used to access things of any other non-character integer type-- even those whose size and representation are identical . 但是,gcc的作者假定不会使用指向非字符整数类型的指针来访问任何其他非字符整数类型的对象, 即使它们的大小和表示形式相同 。 Since
printf
would use a long long int*
to read a parameter for %lld
, a long*
to read one for %ld
, and an int*
to read one for %d
, the authors of gcc would view any attempt to use a %lld
to process an argument of type int64_t
as Undefined Behavior on implementations where that type is defined as something other than long long
, even if its size and representation would be as expected. 由于
printf
将使用long long int*
读取%lld
的参数,使用long*
读取%ld
,使用int*
读取%d
,因此gcc的作者将查看使用%lld
任何尝试。 %lld
将int64_t
类型的参数作为未定义行为处理,该实现被定义为除long long
之外的其他类型,即使其大小和表示形式符合预期。
(*)While C89 requires that all "extensions" be documented, the annex which lists common extensions doesn't list it. (*)虽然C89要求记录所有“扩展名”,但列出常用扩展名的附件未列出。 Since the authors of the Standard cannot plausibly have been unaware that many--if not most--compilers have two or more integer types that share the same size and representation, and allow pointers to those types to be used interchangeably, the only reasonable conclusion would be that they did not regard such behavior as an "extension" that would require documentation.
由于本标准的作者不可能合理地意识到许多编译器(如果不是大多数的话)具有两个或更多个共享相同大小和表示形式的整数类型,并且允许将这些类型的指针互换使用,因此唯一合理的结论是就是他们没有将这种行为视为需要文档记录的“扩展”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.