C++ Can';t将uint64_t与rdrand一起使用,因为它需要无符号long-long,但uint64_t被定义为无符号long
我在尝试使用rdrand Injective时遇到了以下麻烦 在我当前的编译器中,C++ Can';t将uint64_t与rdrand一起使用,因为它需要无符号long-long,但uint64_t被定义为无符号long,c++,long-integer,portability,intrinsics,rdrand,C++,Long Integer,Portability,Intrinsics,Rdrand,我在尝试使用rdrand Injective时遇到了以下麻烦 在我当前的编译器中,unsigned long和unsigned long都是64位的。但是,uint64_t被定义为无符号长,而和64_步骤需要指向无符号长的指针 在英特尔网站上,该函数被定义为int\u rdrand64\u步长(unsigned\u int64*val)。我怎样才能以便于携带的方式处理这个问题 #include <immintrin.h> #include <stdint.h> u
unsigned long
和unsigned long
都是64位的。但是,uint64_t被定义为无符号长
,而和64_步骤
需要指向无符号长
的指针
在英特尔网站上,该函数被定义为int\u rdrand64\u步长(unsigned\u int64*val)
。我怎样才能以便于携带的方式处理这个问题
#include <immintrin.h>
#include <stdint.h>
uint64_t example_rdrand64()
{
uint64_t n;
_rdrand64_step(&n);
return n;
}
使用
无符号长n代码>
您仍然可以将其作为uint64\u t
返回
它与所有4个主要x86编译器(GCC、clang、ICC、MSVC)的当前版本兼容。注意,<>代码> OrrdRand 64步ST/<代码>只适用于X86—64 C++实现,因此限制了可移植性的范围。
所有4个主流x86编译器都使用与unsigned long long
兼容的类型定义\rdrand64\u step
,因此在这种情况下,只需遵循clang的头就可以了。
不幸的是(或不是),gcc/clang的immintrin.h实际上没有定义一个\uu int64
类型来匹配英特尔的intrinsics文档,否则您可以使用它。ICC和MSVC确实允许您实际使用未签名\uu int64 n
。()
immintrin.h
完全可用意味着编译器环境和类型宽度,而且未来的某些x86-64 C实现不太可能(但并非不可能)使unsigned long-long
成为qword(uint64_t)以外的任何东西
虽然如果他们这样做了,也许他们只是将英特尔的\uuu int64
映射到另一种类型,因为英特尔的文档从不使用long
或long
,只是\uu int64
,例如AVX2\u mm256\u maskload\u epi64(\uu int64 const*mem\u addr,\uu m256i mask)
。(甚至对于movq
内部加载:\uuum128i\umm\uloadl\uepi64(\uuuum128i const*mem\u addr)
很久以后,引入了一种更理智的
\uuuuum128i\umm\uloadu\u si64(void const*mem\u addr)
(以及AVX512内部函数)
<>但仍然是一个C++代码实现,它的代码长度不超过64位,可能会破坏一些内联代码,因此,这不是一个需要花费任何时间去担心的问题。在这个例子中,如果它更宽,那仍然是好的。你只需要返回它的低64位,在这里<代码>4~步骤(& n);< /COD>将结果放在一起。(或者,如果C++实现有本征取<代码>未签名长< /C> >,但也会得到编译错误,但是它们定义了<代码> UTIN 64×t <代码>,而不是<代码>未签名的长long < />代码>
在任何假设的未来C++实现中,沉默数据的缺失/截断概率是零。ISO C++保证<强> <代码>无符号长long < /代码>至少是64位类型>(实际上按值范围指定,并且其值位是纯二进制但相同的差异是无符号的)。
您不需要可移植到DeathStation 9000,只需要移植到任何人可能真正想要使用的任何假设的未来编译器,这几乎意味着它将希望与现有的Intel intrinsics代码库兼容,如果它提供这种类型的intrinsics的话。(而不是用不同的名称和类型从头重新设计,在这种情况下,您必须更改此函数中的两行才能使其工作。)使用
无符号长n;
有什么问题吗?这会失败吗\r随机64\u步骤(unsigned\u int64*val)
?@chux>我担心的是,由于英特尔用\uu int64
定义了内在函数,因此如果我使用unsigned long
,可能会有一个编译器(或未来的编译器)用unsigned long
定义内在函数,导致此代码中断。
error: no matching function for call to '_rdrand64_step'
note: candidate function not viable: no known conversion
from 'unsigned int *' to 'unsigned long long *' for 1st argument
_rdrand64_step(unsigned long long *__p)