2016-04-23 8 views
1

Der folgende CodeOSX vs Linux: Wie mit unsigned lange und Uint64_t umgehen?

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

kehrt yes wenn auf Linux kompiliert und no wenn auf OSX zusammengestellt.

Ich lese beim Versuch zu verstehen, warum das war apparently normal. Wie kann ich damit umgehen, wenn ich eine Bibliothek entwickle und möchte, dass sie tragbar ist? Muss ich mit den Präferenzen jedes Betriebssystems umgehen? Hier

ein Beispiel:

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

Als Teil meiner Bibliothek, die vorherige kompiliert und dann verknüpft wenn ich eine ausführbare Datei erstellen muss (zB main.cpp). Normalerweise sieht das so aus:

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

Das wird auf einer Plattform funktionieren, aber in der anderen fehlschlagen; Wenn ich DEFINE_FOO(unsigned long,'l') in foo.cpp auskommentieren, dann ist OSX glücklich, aber Linux sagt Foo<uint64_t> wird neu definiert. Und umgekehrt.

Wie kann das normal sein? Gibt es einen "tragbaren" Weg, damit umzugehen?

Antwort

1

Um es tragbar zu machen, würde ich die Makro-Anrufe mit #ifdef conditionals nach dem Ziel-Betriebssystem mit this list, wie einschließen:

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

Bitte beachte, dass ich uint64_t als l gesetzt, da unsigned long und uint64_t sind in 64-Bit-Architekturen mit gcc ziemlich gleichwertig.

+0

Holy Moly, diese Liste ist sehr lang :) – Sheljohn

+0

Alles, was Sie brauchen, ist Ihr System mit einem guten alten überprüfen ** Find in Page ** :). Beachten Sie auch die Kompatibilität des Flags mit den Compilern. –

Verwandte Themen