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

时间:2016-04-23 17:21:54

标签: c++ linux macos c++11

以下代码

#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

我在尝试理解为什么这是apparently normal时读到了。 如果我正在开发一个库并且我希望它是可移植的,我该如何处理?我是否必须处理每个操作系统的偏好?

以下是一个例子:

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

作为我的库的一部分,在我需要创建可执行文件(比如main.cpp)时,会编译先前的链接然后进行链接。通常,这看起来像:

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

这将在一个平台上工作但在另一个平台上失败;如果我在DEFINE_FOO(unsigned long,'l')中取消注释foo.cpp,那么OSX很高兴,但Linux说Foo<uint64_t>正在被重新定义。反之亦然。

这怎么可能是正常的?有没有&#34;便携式&#34;处理这个的方法?

1 个答案:

答案 0 :(得分:1)

为了使其可移植,我将#ifdef包含宏调用  使用this list根据目标操作系统的条件,例如:

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

请注意,我将uint64_t设置为l,因为unsigned longuint64_t在使用gcc的64位架构中非常相同。