C++ Can';t将uint64_t与rdrand一起使用,因为它需要无符号long-long,但uint64_t被定义为无符号long

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

我在尝试使用rdrand Injective时遇到了以下麻烦

在我当前的编译器中,
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)