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

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

本文关键字:chrono uration rep printf std 位和 程序      更新时间:2023-10-16

有这段代码:

#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类型。

有没有一种便携式的方式来打印它,就像%zusize_t的说明符一样?

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

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

为了避免显式强制转换,您还可以直接使用数据类型而不是自动说明符:

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

1对于所需的最小数据类型,我的意思是可以在两个实现中表示值的最小类型。
2long long int类型必须至少为 64 位宽,请参阅此处的 SO。

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

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

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


但是,如果必须使用 printf,请更改以下内容:

printf("%lld", d);

对此:

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

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

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

一种可移植(即C++)方法,不使用std::cout

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

或者也许

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

为了避免警告,您可以将 d 转换为长整型。

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

也许与手头的 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
)
);
}