为什么 GCC 原子内置函数需要一个额外的 "generic" 版本?
Why do GCC atomic builtins need an additional "generic" version?
根据 https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html,有:
type __atomic_load_n (type *ptr, int memorder)
和("generic"):
void __atomic_load (type *ptr, type *ret, int memorder)
然后
void __atomic_store_n (type *ptr, type val, int memorder)
和("the generic")
void __atomic_store (type *ptr, type *val, int memorder)
等等
后一个版本有什么通用之处(前一个版本不通用)以及为什么需要它们?
section 6.55 中的 GCC 手册中的答案是正确的,它说:
The ‘__atomic’ builtins can be used with any integral scalar or pointer type that is 1, 2, 4, or 8 bytes in length. 16-byte integral types are also allowed if ‘__int128’ (see __int128) is supported by the architecture.
The four non-arithmetic functions (load, store, exchange, and compare_exchange) all have a generic version as well. This generic version works on any data type. It uses the lock-free built-in function if the specific data type size makes that possible; otherwise, an external call is left to be resolved at run time. This external call is the same format with the addition of a ‘size_t’ parameter inserted as the first parameter indicating the size of the object being pointed to. All objects must be the same size.
根据 https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html,有:
type __atomic_load_n (type *ptr, int memorder)
和("generic"):
void __atomic_load (type *ptr, type *ret, int memorder)
然后
void __atomic_store_n (type *ptr, type val, int memorder)
和("the generic")
void __atomic_store (type *ptr, type *val, int memorder)
等等
后一个版本有什么通用之处(前一个版本不通用)以及为什么需要它们?
section 6.55 中的 GCC 手册中的答案是正确的,它说:
The ‘__atomic’ builtins can be used with any integral scalar or pointer type that is 1, 2, 4, or 8 bytes in length. 16-byte integral types are also allowed if ‘__int128’ (see __int128) is supported by the architecture.
The four non-arithmetic functions (load, store, exchange, and compare_exchange) all have a generic version as well. This generic version works on any data type. It uses the lock-free built-in function if the specific data type size makes that possible; otherwise, an external call is left to be resolved at run time. This external call is the same format with the addition of a ‘size_t’ parameter inserted as the first parameter indicating the size of the object being pointed to. All objects must be the same size.