简体   繁体   English

C99:为什么%lli与64位计算机上的int64_t不匹配?

[英]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的大小和表示形式与shortlong

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任何尝试。 %lldint64_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM