_InterlockedCompareExchange文档中"The sign is ignored"的含义
Meaning of "The sign is ignored" in _InterlockedCompareExchange documentation
_InterlockedCompareExchange
的文档说每个参数
标志被忽略。
那么,这是否意味着0xffff
和0x7fff
(对于16位版本)等数字将被_InterlockedCompareExchange16
等视为其他宽度内在的数字吗?还是这意味着内在的签名和未签名的整数?还是其他?
如果它不是文档中的错误,则似乎至少模棱两可。
符号位不被忽略,就像其他位一样比较。
..CompareExchange..
的功能仅关心位的平等性,并且不会以任何特殊的方式解释它们。在基于X86的系统上,它们通过CMPXCHG
/CMPXCHG8B
指令实现,并将CPU寄存器与内存位置进行比较。符号问题成为有关类型和参数传递的问题,而不是比较本身。
由于大多数互锁功能也存在作为Windows API函数,因此我们可以首先查看这些功能。基本版本使用LONG
类型采用32位参数。较小的签名类型将被签名到32位:
__declspec(noinline) void WINAPI Number(LONG val)
{
printf("Number: %5d %#.8x (%d bit)n", val, val, sizeof(void*) * 8);
}
__declspec(noinline) INT16 WINAPI GetI16(INT16 num)
{
return num;
}
...
Number(0xffff); // Not sign extended
const INT16 numi16 = -42;
Number(numi16); // Optimized to 32-bit parameter by the compiler
Number(GetI16(-42)); // Use a helper function to prevent compiler tricks
此打印:
Number: 65535 0x0000ffff (64 bit)
Number: -42 0xffffffd6 (64 bit)
Number: -42 0xffffffd6 (64 bit)
32位x86:
; 1040 : Number(0xffff);
00022 68 ff ff 00 00 push 65535 ; 0000ffffH
00027 e8 00 00 00 00 call ?Number@@YGXJ@Z ; Number
; 1041 : const INT16 numi16 = -42;
; 1042 : Number(numi16);
0002c 6a d6 push -42 ; ffffffd6H
0002e e8 00 00 00 00 call ?Number@@YGXJ@Z ; Number
; 1047 : Number(GetI16(-42));
00033 6a d6 push -42 ; ffffffd6H
00035 e8 00 00 00 00 call ?GetI16@@YGFF@Z ; GetI16
0003a 0f bf c0 movsx eax, ax
0003d 50 push eax
0003e e8 00 00 00 00 call ?Number@@YGXJ@Z ; Number
64位x86_64/amd64:
; 1040 : Number(0xffff);
00027 b9 ff ff 00 00 mov ecx, 65535 ; 0000ffffH
0002c e8 00 00 00 00 call ?Number@@YAXJ@Z ; Number
; 1041 : const INT16 numi16 = -42;
; 1042 : Number(numi16);
00031 b9 d6 ff ff ff mov ecx, -42 ; ffffffffffffffd6H
00036 e8 00 00 00 00 call ?Number@@YAXJ@Z ; Number
; 1047 : Number(GetI16(-42));
0003b 66 b9 d6 ff mov cx, -42 ; ffffffffffffffd6H
0003f e8 00 00 00 00 call ?GetI16@@YAFF@Z ; GetI16
00044 0f bf c8 movsx ecx, ax
00047 e8 00 00 00 00 call ?Number@@YAXJ@Z ; Number
我们可以看到生成的代码使用MOVSX
签名扩展16位号。这是Windows Abi的要求。
当您使用#pragma intrinsic(_InterlockedCompareExchange)
时,事情还不太清楚。我在文档中找不到有关内在函数ABI的确定性语句,但是我们可以假设它在签名扩展时遵循Windows ABI。编译器将直接生成LOCK CMPXCHG
指令,而无需函数调用,但需要在需要时使用MOVSX
。
_InterlockedCompareExchange
这是以CMPXCHG
指令实现的编译器的固有性。The sign is ignored
意味着,当我们将2个整数与相等的仅比较时 - 我们如何解释高位 - 为符号或否。这仅与>
或<
进行比较,但不适合=
。0xffff
当然不等于0x7fff
- Why is UINT32_MAX + 1 = 0?
- C++错误:"error: int aaa::bbb is protected within this context"
- 创建具有 new in 函数和"this is nullptr"异常的对象
- 使用 cmake 的 Linux 终端上的"Conversion to non-scalar type is requested"错误
- Is !NaN not a NaN?
- 为什么我会" void value not ignored as it ought to be"?
- Directx 11 - CompileFromFile() is not compiling
- Centos7 g++ "to_string is not in a member of std"
- "Unable to start debugging. No process is associated with this object." - 在Visual Studio Code中使用GDB
- Where is std::hardware_destructive_interference_size?
- 将成员函数作为构造函数参数调用时出错 "Variable is not a type name"
- What is unordered_set in C++
- 你如何理解"std: :forward is just syntactic sugar"?这是真的吗?
- C++ "error: use of overloaded operator '*' is ambiguous"似乎只有一场比赛
- C++ is calculating wrong
- Is it good to use SDL_PIXELFORMAT_UNKNOWN?
- 为什么编译器说"candidate template ignored: couldn't infer template argument 'InputIterator'"?
- reference_wrapper导致"incomplete type is not allowed"
- _InterlockedCompareExchange文档中"The sign is ignored"的含义
- 错误是什么意思"void-value is not ignored"以及如何删除它?