简体   繁体   English

在32位和64位程序中使用std :: chrono :: duration :: rep和printf

[英]Using std::chrono::duration::rep with printf in 32bit and 64bit programs

There is this code: 有这个代码:

#include <cstdio>
#include <chrono>

int main()
{
  auto d = std::chrono::microseconds(1).count();
  printf("%lld", d);
  return 0;
}

When this is compiled in 64bit mode, then there is a warning: 当在64位模式下编译时,会出现警告:

 main.cpp: In function 'int main()': main.cpp:7:19: warning: format '%lld' expects argument of type 'long long int', but argument 2 has type 'long int' [-Wformat=] printf("%lld", d); ^ 

This warning is not present when compiling in 32bit mode (with -m32 flag). 在32位模式下编译时使用此警告(使用-m32标志)。 It looks like that std::chrono::duration::rep is of type long int in 64bit programs and long long int in 32bit programs. 看起来std::chrono::duration::rep在64位程序中是long int类型,在32位程序中是long long int

Is there a portable way to print it like %zu specifier for size_t ? 是否有可移植的方式来打印它像size_t %zu说明符?

As you said that the usage of std::cout is not an option you can cast the value to the smallest needed data type 1 here it's long long int 2 and use the corresponding conversion specifier: 正如您所说, std::cout的使用不是一个选项,您可以将值转换为所需的最小数据类型1,这里它是long long int 2并使用相应的转换说明符:

printf("%lld", static_cast<long long int>(d));

To avoid the explicit cast you can also use the data type directly instead of the auto specifier : 要避免显式转换,您还可以直接使用数据类型而不是auto说明符

long long int d = std::chrono::microseconds(1).count();
printf("%lld", d);

1 With smallest needed data type I mean the smallest type that can represent the value in both implementations. 1对于所需的最小数据类型,我指的是可以表示两种实现中的值的最小类型。
2 The long long int type has to be at least 64 bit wide, see here on SO . 2 long long int类型必须至少为64位宽, 请参见SO

I suggest you use std::cout , since you are in C++. 我建议你使用std::cout ,因为你使用的是C ++。 This will be portable. 这将是便携式的。


However, if you must use printf, change this: 但是,如果必须使用printf,请更改:

printf("%lld", d);

to this: 对此:

#include <cinttypes>
printf("%" PRId64 "", d); 

Another approach would be to cast d to the highest data type (which can hold both types), like this: 另一种方法是将d转换为最高数据类型(可以包含两种类型),如下所示:

printf("%lld", static_cast<long long int>(d));

You can cast it to long long int before printing: 您可以在打印前将其强制转换为long long int

#include <cstdio>
#include <chrono>

int main()
{
  auto d = std::chrono::microseconds(1).count();
  printf("%lld", static_cast<long long int>(d));
  return 0;
}

But it seems me that it is better to use std::cout 但似乎我最好使用std::cout

Instead of using the auto qualifier, use a fixed size integer int64_t. 而不是使用auto限定符,使用固定大小的整数int64_t。

#include <cstdio>
#include <chrono>
#include <cinttypes>

int main()
{
    int64_t d = std::chrono::microseconds(1).count();
    printf("%" PRId64 "\n", d);
    return 0;
}

A portable (ie C++) approach to consider, that does not use std::cout 一种便携式(即C ++)方法,不使用std :: cout

 {
   // create a string:
   std::ostringstream ss; 
   ss << d;" 
   // then
   printf("%s", ss.str().c_str());
 } 

or perhaps 也许

 {
   printf("%s", std::to_string(d).c_str() );
 }

为了避免警告,你可以将d转换为long long int。

printf("%lld", static_cast<long long int> (d));

Perhaps not directly related to the 32/64 bit problem at hand, but some of us are on embedded systems with odd output consoles and C++ libraries. 也许与手头的32/64位问题没有直接关系,但是我们中的一些人在具有奇数输出控制台和C ++库的嵌入式系统上。 (Plus we know that if we have to do any serious output formatting, printf is saner than iomanip!) (另外我们知道如果我们必须进行任何严格的输出格式化,printf比iomanip更安全!)

Anyway, this prints the guts of a duration and may be useful for debugging. 无论如何,这会打印持续时间的内容,可能对调试很有用。 Modify to taste. 修改味道。

template<typename Rep, typename Ratio>
printf_dur( std::chrono::duration< Rep, Ratio > dur )
{
    printf( "%lld ticks of %lld/%lld == %.3fs",
            (long long int) dur.count(),
            (long long int) Ratio::num,
            (long long int) Ratio::den,
            ( (Ratio::num == 1LL)
              ? (float) dur.count() / (float) Ratio::den
              : (float) dur.count() * (float) Ratio::num
            )
         );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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