[英]Can't use uint64_t with rdrand as it expects unsigned long long, but uint64_t is defined as unsigned long
[英]OSX vs Linux: how to deal with unsigned long and uint64_t?
以下代码
#include <cstdio>
#include <cstdint>
#include <type_traits>
int main()
{
static const char* b2s[] = { "no", "yes" };
printf( "%s\n", b2s[std::is_same<unsigned long, uint64_t>::value] );
}
在 Linux 上编译时返回yes
,在 OSX 上编译时返回no
。
我一边读一边试图理解为什么这显然是正常的。 如果我正在开发一个库并且我希望它是可移植的,我该如何处理? 我是否必须处理每个操作系统的偏好?
下面是一个例子:
foo.h
#include <cstdint>
template <class T>
struct Foo
{
static const char id;
};
文件
#include "foo.h"
#define DEFINE_FOO(type_,id_) \
template <> const char Foo<type_>::id = id_; \
template <> const char Foo<const type_>::id = id_;
DEFINE_FOO( bool,'a')
DEFINE_FOO( int8_t,'b')
DEFINE_FOO( uint8_t,'c')
DEFINE_FOO( int16_t,'d')
DEFINE_FOO(uint16_t,'e')
DEFINE_FOO( int32_t,'f')
DEFINE_FOO(uint32_t,'g')
DEFINE_FOO( int64_t,'h')
DEFINE_FOO(uint64_t,'i')
DEFINE_FOO( float,'j')
DEFINE_FOO( double,'k')
// OSX requires this, but Linux considers it a re-definition
// DEFINE_FOO(unsigned long,'l')
作为我的库的一部分,前一个被编译,然后在我需要创建可执行文件(比如main.cpp
)时链接。 通常,这看起来像:
$(CC) -c -Wall -std=c++0x -o foo.o foo.cpp
$(CC) -Wall -std=c++0x -o main main.cpp foo.o
这将在一个平台上工作,但在另一个平台上失败; 如果我在foo.cpp
取消注释DEFINE_FOO(unsigned long,'l')
那么 OSX 很高兴,但 Linux 说Foo<uint64_t>
正在被重新定义。 反之亦然。
怎么可能正常? 有没有一种“便携”的方式来处理这个问题?
为了使其可移植,我会根据使用此列表的目标操作系统使用#ifdef
条件将宏调用括起来,例如:
#ifdef __linux__
DEFINE_FOO(uint64_t,'l')
#endif
[...]
#ifdef __APPLE__
DEFINE_FOO(unsigned long,'l')
#endif
请注意,我将uint64_t
设置为l
因为unsigned long
和uint64_t
在具有 gcc 的 64 位体系结构中几乎等效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.