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

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

有这个代码:

#include <cstdio>
#include <chrono>

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

在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);
                   ^

在 32 位模式(使用 -m32 标志)下编译时不会出现此警告。看起来 std::chrono::duration::rep 在 64 位程序中是 long int 类型,在 32 位程序中是 long long int 类型。

有没有像 size_t%zu 说明符那样的便携式打印方式?

我建议您使用 std::cout,因为您使用的是 C++。这将是便携式的。


但是,如果您必须使用 printf,请更改为:

printf("%lld", d);

对此:

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

另一种方法是将 d 转换为最高数据类型(可以容纳两种类型),如下所示:

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

您可以在打印前将其转换为 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;
}

不过我觉得还是用std::cout

正如您所说,用法 of std::cout 不是一个选项,您可以将值转换为所需的最小数据类型1,这里是 long long int2 并使用相应的转换说明符:

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

为了避免显式转换,您也可以直接使用数据类型而不是 auto specifier:

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

1 对于最小的所需数据类型,我指的是可以在两种实现中表示值的最小类型。
2 long long int 类型必须至少为 64 位宽,see here on SO.

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

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

不使用 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;
}

考虑一种不使用 std::cout

的可移植(即 C++)方法
 {
   // create a string:
   std::ostringstream ss; 
   ss << d;" 
   // then
   printf("%s", ss.str().c_str());
 } 

或者也许

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

也许与手头的 32/64 位问题没有直接关系,但我们中的一些人使用的嵌入式系统具有奇怪的输出控制台和 C++ 库。 (另外我们知道,如果我们必须进行任何严肃的输出格式化,printf 比 iomanip 更明智!)

无论如何,这会打印持续时间的内容,可能对调试有用。修改口味。

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
            )
         );
}