std::compare_exchange 具有#define 值的整数
std::compare_exchange int with #define value
- 我想用
std::compare_exchange_strong
一些 std::atomic<int>
- 由于编译原因(
int &
) 被迫引入int _OLD_VALUE = OLD_VALUE
.
- 有没有更优雅的方法来实现这个?
- 这是我的例子
#include <atomic>
#include <stdio.h>
#define OLD_VALUE 16
#define NEW_VALUE 744
#define OTHER_VALUE 80
int main(int argc, char **argv)
{
std::atomic<int> i(OTHER_VALUE);
int _OLD_VALUE = OLD_VALUE;
bool status = i.compare_exchange_strong(_OLD_VALUE,NEW_VALUE);
// bool status = i.compare_exchange_strong( OLD_VALUE,NEW_VALUE);
if (status) { printf("good\n"); }
return 0;
}
这里是我使用注释版本时的编译错误:
main.cpp: In function ‘int main(int, char**)’:
main.cpp:11:65: error: cannot bind non-const lvalue reference of type ‘std::__atomic_base<int>::__int_type& {aka int&}’ to an rvalue of type ‘int’
bool status = i.compare_exchange_strong( OLD_VALUE,NEW_VALUE);
^
In file included from /usr/include/c++/7/atomic:41:0,
from main.cpp:1:
/usr/include/c++/7/bits/atomic_base.h:496:7: note: initializing argument 1 of ‘bool std::__atomic_base<_IntTp>::compare_exchange_strong(std::__atomic_base<_IntTp>::__int_type&, std::__atomic_base<_IntTp>::__int_type, std::memory_order) [with _ITp = int; std::__atomic_base<_IntTp>::__int_type = int; std::memory_order = std::memory_order]’
compare_exchange_strong(__int_type& __i1, __int_type __i2,
^~~~~~~~~~~~~~~~~~~~~~~
没有。原因是变量的先前值被交换,因此如果比较不匹配,expected
值将被覆盖。
要了解幕后发生的事情,请查看 GCC built-ins:
https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
您会注意到 GCC (Linux) 的内置函数中有一个 __atomic_exchange_n
,但它只是提供一个交换而不是 compare-and-swap。 Windows 等价于 InterlockedExchange
: https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-interlockedexchange
为了可读性,我会避免在变量名中使用大写字母并避免前导下划线:
int oldValue = OLD_VALUE;
实现此目的的最简单方法(我想也是唯一的方法)是编写简单的包装器:
bool cas_strong(std::atomic<int>& a, int cmp, int exc) {
return a.compare_exchange_strong(cmp, exc);
}
不要使用宏来定义值:
#include <atomic>
#include <stdio.h>
int OLD_VALUE 16
int NEW_VALUE 744
int OTHER_VALUE 80
int main(int argc, char **argv)
{
std::atomic<int> i(OTHER_VALUE);
bool status = i.compare_exchange_strong( OLD_VALUE,NEW_VALUE);
if (status) { printf("good\n"); }
return 0;
}
compare_exchange_strong
期望 int&
存储在 i
中找到的当前值。在这里,您间接提供 16
(即您的宏 OLD_VALUE
在 pre-processing 处被替换的内容),它是一个整数 compile-time 常量,a.k.a。 constexpr int&
。这与 int&
.
不兼容
要提供 int&
,您最好在 compare_exchange_strong
:
的调用附近保留 int
std::atomic<int> i(OTHER_VALUE);
int old_value = OLD_VALUE;
bool status = i.compare_exchange_strong(old_value, NEW_VALUE);
if (status) { printf("good\n"); }
return 0;
此外,更一般地说,如果您在这里使用静态常量而不是宏,显然会更强大。
在另一个问题中有更多相关信息:What is the difference between a macro and a const in C++?
- 我想用
std::compare_exchange_strong
一些std::atomic<int>
- 由于编译原因(
int &
) 被迫引入int _OLD_VALUE = OLD_VALUE
. - 有没有更优雅的方法来实现这个?
- 这是我的例子
#include <atomic>
#include <stdio.h>
#define OLD_VALUE 16
#define NEW_VALUE 744
#define OTHER_VALUE 80
int main(int argc, char **argv)
{
std::atomic<int> i(OTHER_VALUE);
int _OLD_VALUE = OLD_VALUE;
bool status = i.compare_exchange_strong(_OLD_VALUE,NEW_VALUE);
// bool status = i.compare_exchange_strong( OLD_VALUE,NEW_VALUE);
if (status) { printf("good\n"); }
return 0;
}
这里是我使用注释版本时的编译错误:
main.cpp: In function ‘int main(int, char**)’:
main.cpp:11:65: error: cannot bind non-const lvalue reference of type ‘std::__atomic_base<int>::__int_type& {aka int&}’ to an rvalue of type ‘int’
bool status = i.compare_exchange_strong( OLD_VALUE,NEW_VALUE);
^
In file included from /usr/include/c++/7/atomic:41:0,
from main.cpp:1:
/usr/include/c++/7/bits/atomic_base.h:496:7: note: initializing argument 1 of ‘bool std::__atomic_base<_IntTp>::compare_exchange_strong(std::__atomic_base<_IntTp>::__int_type&, std::__atomic_base<_IntTp>::__int_type, std::memory_order) [with _ITp = int; std::__atomic_base<_IntTp>::__int_type = int; std::memory_order = std::memory_order]’
compare_exchange_strong(__int_type& __i1, __int_type __i2,
^~~~~~~~~~~~~~~~~~~~~~~
没有。原因是变量的先前值被交换,因此如果比较不匹配,expected
值将被覆盖。
要了解幕后发生的事情,请查看 GCC built-ins: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
您会注意到 GCC (Linux) 的内置函数中有一个 __atomic_exchange_n
,但它只是提供一个交换而不是 compare-and-swap。 Windows 等价于 InterlockedExchange
: https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-interlockedexchange
为了可读性,我会避免在变量名中使用大写字母并避免前导下划线:
int oldValue = OLD_VALUE;
实现此目的的最简单方法(我想也是唯一的方法)是编写简单的包装器:
bool cas_strong(std::atomic<int>& a, int cmp, int exc) {
return a.compare_exchange_strong(cmp, exc);
}
不要使用宏来定义值:
#include <atomic>
#include <stdio.h>
int OLD_VALUE 16
int NEW_VALUE 744
int OTHER_VALUE 80
int main(int argc, char **argv)
{
std::atomic<int> i(OTHER_VALUE);
bool status = i.compare_exchange_strong( OLD_VALUE,NEW_VALUE);
if (status) { printf("good\n"); }
return 0;
}
compare_exchange_strong
期望 int&
存储在 i
中找到的当前值。在这里,您间接提供 16
(即您的宏 OLD_VALUE
在 pre-processing 处被替换的内容),它是一个整数 compile-time 常量,a.k.a。 constexpr int&
。这与 int&
.
要提供 int&
,您最好在 compare_exchange_strong
:
int
std::atomic<int> i(OTHER_VALUE);
int old_value = OLD_VALUE;
bool status = i.compare_exchange_strong(old_value, NEW_VALUE);
if (status) { printf("good\n"); }
return 0;
此外,更一般地说,如果您在这里使用静态常量而不是宏,显然会更强大。 在另一个问题中有更多相关信息:What is the difference between a macro and a const in C++?