如何打印std::atomic<unsigned int>的值?

21
我在我的程序中使用了std::atomic<unsigned int>。我该如何使用printf打印它的值?如果我只使用%u,它不起作用。我知道我可以使用std::cout,但是我的程序中到处都是printf调用,我不想替换每一个调用。以前我使用的是unsigned int而不是std::atomic<unsigned int>,所以我只需要在printf调用的格式字符串中使用%u,打印就能正常工作。
现在,当我尝试打印std::atomic<unsigned int>而不是常规的unsigned int时,我得到的错误是:

error: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘std::atomic<unsigned int>’ [-Werror=format=]


如果你能展示你尝试过的代码以及它为何不起作用(输出或错误信息),那可能会有所帮助。 - crashmstr
5
std::atomic<> 类有一个 load() 成员函数,用于读取值(原子地 :-),你可以使用它。 - Bo Persson
你真的需要一个原子变量吗?std::atomic用于为并发问题对变量进行内存访问排序。 - AJG85
2
是的,AJG85,这正是我使用std::atomic的原因。 - MetallicPriest
请在问题中添加一个样本错误或警告,以便任何使用谷歌搜索的人可以找到。例如:error: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘std::atomic<unsigned int>’ [-Werror=format=]。我认为这个错误适用于这个问题。至少现在是我的错误。 - Gabriel Staples
有趣的事实:MSVC19.10(VS2015)无法拒绝printf("%u", atomic_var)。https://godbolt.org/z/ceWvhKbvn显示它实际上将`std::atomic<>对象复制到堆栈中,而不仅仅是底层的T。(与大多数实现不同,当MSVC的std::atomic无法无锁时,它在对象本身中包含一个互斥锁。因此,sizeof(atomic<big>) == 36,而底层结构体为32,我们看到它使用了2个movups加上额外的4字节mov`)。因此,在只使用较旧的MSVC进行测试的代码库中可能存在此类错误。似乎在MSVC19.10(VS2017及更高版本)中已修复。 - undefined
2个回答

28

另一种选择是使用 atomic 变量的 load() 方法。例如:

std::atomic<unsigned int> a = { 42 };
printf("%u\n", a.load());

16
template<typename BaseType>
struct atomic
{
    operator BaseType () const volatile;
}
使用类型转换来提取底层值。
printf("%u", unsigned(atomic_uint));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接