…für Plattform- und Compilerübergreifende Programme (Stichwort: Portabilität)
Zuerst kommt die Ermittlung/Bestimmung des Compilers und danach der Plattform, weil viele Makros vom Compiler selbst gesetzt werden und sind deshalb Compiler-abhängig.
Eine große Übersicht von Makros im Bezug auf Compiler und Plattforme sind hier zu finden:
Anhand folgender Makros läßt sich feststellen, mit welchem Compiler der Quelltext übersetzt wird:
| Makro | Kommentar |
|---|---|
| __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ | Der GNU C-Compiler setzt diese Makros. Beispiel: // Test for GCC > 3.2.0 #if __GNUC__ > 3 || (__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || (__GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ > 0)) #endif …oder: #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) // Test for GCC > 3.2.0 #if GCC_VERSION > 30200 #endif |
| __GNUG__ | Der GNU C++-Compiler setzt dieses Makro. Es ist equivalent zum Test auf (__GNUC__ && __cplusplus). |
| __CYGWIN__ __CYGWIN32__ | Der Cygwin-Compiler (POSIX, Portierung von GCC unter Windows) setzt diese Makros. |
| __MINGW32__ __MINGW64__ | Der MinGW-Compiler (non-POSIX, minimalistische Portierung von GCC unter Windows) setzt diese Makros. |
| _MSC_VER | Der MS VisualStudio-Compiler (häufig "VC" oder "MSVC" genannt) setzt dieses Makro mit dem Wert, der gleichzeitig der internen Compiler-Version entspricht. Hier ist die Auflistung, welche Werte welcher Version des MSVC-Compilers entsprechen: https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B#Internal_version_numbering |
Quelle: https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
Weitere Compiler:
Sprach-Level:
| Makro | Kommentar |
|---|---|
| __cplusplus | Definiert nur, wenn der Text von einem C++-Compiler übersetzt wird. Einige Werte, die dieses Makro haben kann: 201103L = "C++11", 201402L = "C++14". Beispiel 1: Prüfung, ob der passende Compiler verwendet wird: // Es muss mindestens C++11 sein: #if (__cplusplus < 201103L) #error ---------- C++11 features not available - use the GCC-option -std=c++11 ---------- #endif
#if (__cplusplus < 201402L) // vor C++14 #include <memory> namespace std { template<typename T, typename ...Args> std::unique_ptr<T> make_unique(Args&& ...args) { return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); } } #endif |
IN ARBEIT - Anfang
Unterscheidung auf HW-Ebene:
HW = Prozessorarchitektur + Bit-Breite + Endianes
Folgende Makros können für die Bestimmung der HW-Ebene herangezogen werden:
Dieses Makros werden durch den MS VisualStudio-Compiler gesetzt:
| Makro | Kommentar |
|---|---|
| _M_AMD64 | Definiert, wenn Target ein x64-Prozessor ist. |
| _M_ARM | Definiert, wenn Target ein ARM-Prozessor ist. |
| _M_IX86 | Definiert, wenn Target ein x86-Prozessor ist. Bei dem x64-Prozessor ist dieses Makro nicht definiert. |
| _M_X64 | Definiert, wenn Target ein x64-Prozessor ist. |
| Makro | Kommentar |
|---|---|
| Makro | Kommentar |
|---|---|
| __BYTE_ORDER__ Mögliche Werte: __ORDER_LITTLE_ENDIAN__ __ORDER_BIG_ENDIAN__ __ORDER_PDP_ENDIAN__ | Das Makro "__BYTE_ORDER__" nimmt wahlweise den Wert den anderen 3 Makros, je nachdem welches Endianes das Target hat. Ein Beispiel: // Test for a little-endian machine: #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #endif |
Unterscheidung auf SW-Ebene:
OS = OS-Familie + OS-Name + Namenszusatz + Bit-Breite
| Makro | Kommentar |
|---|---|
| Windows-Familie | MS VisualStudio-Compiler |
| _WIN32 | Definiert für Win32- und Win64-Anwendungen. (Immer definiert.) Hinweis: Nicht mit "WIN32" (ohne Unterstrich) verwechseln! "_WIN32" wird durch den Compiler gesetzt, "WIN32" durch das SDK oder Build Environment. |
| _WIN64 | Definiert nur für Win64-Anwendungen. |
| UNIXoide | |
| __unix __unix__ | Definiert auf allen / meisten UNIX-artigen Betriebssystemen. |
| _AIX | Definiert unter AIX. |
| sun __sun __sun__ __SVR4 | |
| __FreeBSD__ | FreeBSD. |
| __NetBSD__ | NetBSD. |
| __OpenBSD__ | OpenBSD. |
| __hpux | HP-UX. |
| __APPLE__ __MACH__ | Definiert unter OSX, iOS und Darwin. Zur weiteren Unterscheidung werden Makros aus TargetConditionals.h herangezogen: TARGET_OS_EMBEDDED, TARGET_OS_IPHONE, TARGET_OS_MAC und TARGET_IPHONE_SIMULATOR |
| Linux | |
| __linux__ __gnu_linux__ | Definiert auf Linux-Derivaten. Eigentlich gehört die Linux-Familie auch zu den UNIXoiden, wird hier jedoch übersichtshalber und aufgrund großer Anzahl verschiedener Distributionen separat behandelt. |
_WINDOWS
__i386
__i386__
i386
x86
x64
_X64
__x86_64
__sparc
__sparc__
sparc
_SPARC
| Makro | Kommentar |
|---|---|
| __ELF__ | Dieses Makro ist definiert, wenn Target nutzt das Object-Format ELF. |
Fazit:
Plattform-ID (oder einfach Plattform) = HW + OS
IN ARBEIT - Ende
Viele Plattform-Makros sind im HeaderFile gtest-port.h (aus GoogleTest) enthalten und können sehr gut als Anhaltspunkte verwendet werden.
Stand: 27.09.2019
— : Jürgen Kreick
EOF