简体   繁体   English

OSX vs Linux:如何处理 unsigned long 和 uint64_t?

[英]OSX vs Linux: how to deal with unsigned long and uint64_t?

The following code以下代码

#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] ); 
}

returns yes when compiled on Linux, and no when compiled on OSX.在 Linux 上编译时返回yes ,在 OSX 上编译时返回no

I read while trying on understand why that this was apparently normal .我一边读一边试图理解为什么这显然是正常的 How can I deal with this if I am developing a library and that I want it to be portable?如果我正在开发一个库并且我希望它是可移植的,我该如何处理? Will I have to deal with each OS's preference?我是否必须处理每个操作系统的偏好?

Here is an example:下面是一个例子:

foo.h foo.h

#include <cstdint>

template <class T>
struct Foo
{
    static const char id;
};

foo.cpp文件

#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')

As part of my library, the previous is compiled and then linked when I need to create an executable (say main.cpp ).作为我的库的一部分,前一个被编译,然后在我需要创建可执行文件(比如main.cpp )时链接。 Typically, this looks like:通常,这看起来像:

$(CC) -c -Wall -std=c++0x -o foo.o foo.cpp
$(CC) -Wall -std=c++0x -o main main.cpp foo.o

That will work on one platform but fail in the other;这将在一个平台上工作,但在另一个平台上失败; if I uncomment DEFINE_FOO(unsigned long,'l') in foo.cpp then OSX is happy, but Linux says Foo<uint64_t> is being redefined.如果我在foo.cpp取消注释DEFINE_FOO(unsigned long,'l')那么 OSX 很高兴,但 Linux 说Foo<uint64_t>正在被重新定义。 And vice-versa.反之亦然。

How can that be normal?怎么可能正常? Is there a "portable" way to deal with this?有没有一种“便携”的方式来处理这个问题?

In order to make it portable, I'd enclose the macro calls with #ifdef conditionals according to the target OS using this list , such as:为了使其可移植,我会根据使用此列表的目标操作系统使用#ifdef条件将宏调用括起来,例如:

#ifdef __linux__
DEFINE_FOO(uint64_t,'l')
#endif
[...]
#ifdef __APPLE__
DEFINE_FOO(unsigned long,'l')
#endif

Note that I set uint64_t as l since unsigned long and uint64_t are pretty much equivalent in 64bit architectures with gcc.请注意,我将uint64_t设置为l因为unsigned longuint64_t在具有 gcc 的 64 位体系结构中几乎等效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 不能将 uint64_t 与 rdrand 一起使用,因为它需要 unsigned long long,但 uint64_t 被定义为 unsigned long - Can't use uint64_t with rdrand as it expects unsigned long long, but uint64_t is defined as unsigned long 如何在MongoDB文档中存储unsigned long long(uint64_t)值? - How to store unsigned long long (uint64_t) values in a MongoDB document? 无符号长的类型与Windows上的uint32_t和uint64_t不同(VS2010) - Type of unsigned long is different from uint32_t and uint64_t on Windows (VS2010) 编译器宏来测试uint64_t和unsigned long long int之间的区别 - Compiler macro to test difference between uint64_t and unsigned long long int 如何处理高于7FF的十六进制值…64位和uint64_t类型 - how to deal with hex values higher than 7FF… 64 bits and uint64_t type reinterpret_cast unsigned char * as uint64_t * - 这是UB吗? - reinterpret_cast unsigned char* as uint64_t* - is this UB? 从“ uint64_t”到“ unsigned int”的转换 - conversion from 'uint64_t' to 'unsigned int' C ++:将uint64_t转换为无符号字符数组 - C++ : convert uint64_t to unsigned char array 从二进制文件中将 unsigned int 读入 uint64_t - Reading unsigned int into uint64_t from binary file 如何定义uint64_t常量? - How to define uint64_t constant?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM