Inhaltsverzeichnis
Plattform-Makros
…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:
- "C/C++ tip: How to detect the operating system type using compiler predefined macros" (Stand: 03.01.2012): http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system
- "C/C++ tip: How to list compiler predefined macros" (Stand: 07.12.2011): http://nadeausoftware.com/articles/2011/12/c_c_tip_how_list_compiler_predefined_macros
Compiler
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 |
Plattform
IN ARBEIT - Anfang
Unterscheidung auf HW-Ebene:
- Prozessorarchitektur (z.B. "x86" oder "sparc") - welche Kürzel?
- Bit-Breite (z.B. 32- oder 64-Bit)
- Endianes (z.B. Big-/Little-Endian)
HW = Prozessorarchitektur + Bit-Breite + Endianes
Folgende Makros können für die Bestimmung der HW-Ebene herangezogen werden:
- Prozessorarchitektur:
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. |
- Bit-Breite:
Makro | Kommentar |
---|---|
- Endianes:
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-Familie (z.B. "unix", "linux", "windows")
- OS-Name/-Derivat (innerhalb der Familie, z.B. "solaris", "debian")
- Namenszusatz (z.B. Nummer 6 bei RHEL6 oder 10 bei Windows10)
- Bit-Breite (z.B. 32- oder 64-Bit)
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